<template>
  <div ref="chartContainer" class="d3-chart fffff">
    <!-- 添加定位按钮 -->
    <div class="locate-button" @click="locateCurrentUser">
      <i class="el-icon-position"></i>
    </div>
  </div>

  <!-- 添加搜索框 -->
  <div class="search-container">
    <el-input
      v-model="searchQuery"
      placeholder="搜索家族成员..."
      clearable
      @input="handleSearchInput"
      @clear="clearSearch"
    >
      <template #prefix>
        <i class="el-icon-search"></i>
      </template>
    </el-input>
    <div v-if="searchResults.length > 0" class="search-results">
      <div
        v-for="(result, index) in searchResults"
        :key="index"
        class="search-result-item"
        @click="focusOnSearchResult(result)"
      >
        <img :src="result.photoUrl || getDefaultAvatar({ gender: result.gender, birthDate: result.birthDate })" class="result-avatar" />
        <div class="result-info">
          <div class="result-name">{{result.firstName}}{{result.lastName}}</div>
          <div class="result-generation">{{ result.nameKey }}第{{ result.generation }}代</div>
          <div class="result-generation">{{result.century}}世</div>
          <div class="result-extra">{{result.genation || ''}} {{result.gender === 1 ? '男' : '女'}}</div>
        </div>
      </div>
    </div>
  </div>

  <!-- 接谱专用表单弹窗 -->
  <el-drawer
    v-model="connectDialog.visible"
    :title="'家谱接入'"
    :size="drawerSize"
    @close="handleCloseConnectDialog"
  >
    <el-alert
      title="接谱说明"
      type="info"
      description="您可以直接选择系统推荐的可接入家谱成员，点击确定即可完成接谱。"
      show-icon
      :closable="false"
      style="margin-bottom: 20px;"
    />

    <div class="connect-branch-container">
      <el-form label-width="100px">
        <el-form-item label="当前成员">
          <div class="selected-node-info">
            <img :src="currentNodeInfo.photoUrl || getDefaultAvatar({ gender: 1, birthDate: '' })" class="node-avatar" />
            <div class="node-details">
              <div class="node-name">{{currentNodeInfo.firstName}}{{currentNodeInfo.lastName}} <span class="node-gender">{{currentNodeInfo.gender === 1 ? '男' : '女'}}</span></div>
            </div>
          </div>
        </el-form-item>

        <el-form-item label="接谱成员">
          <el-select
            v-model="connectBranchData.targetId"
            placeholder="请选择可接入的家谱成员"
            style="width: 100%"
            clearable
            :loading="branchSearchLoading"
            @change="handleTargetMemberChange"
          >
            <el-option
              v-for="item in connectBranchOptions"
              :key="item.value"
              :label="`${item.label} (${item.realType == 1 ? '同辈关系':item.realType == 2 ? '父辈关系':item.realType == 3 ? '祖辈关系':'未知关系'}) - ${item.familyName || '未知家谱'}`"
              :value="item.value"
            >
              <div class="connect-branch-option">
                <div class="option-details">
                  <div class="option-name">{{item.label}}({{item.realType == 1 ? '同辈关系':item.realType == 2 ? '父辈关系':item.realType == 3 ? '祖辈关系':'未知关系'}}) - {{item.familyName || '未知家谱'}}</div>
                </div>
              </div>
            </el-option>
          </el-select>
        </el-form-item>

        <!-- 关系图显示区域 -->
        <template v-if="relationTreeData && !relationLoading">
          <el-divider content-position="center">关系预览</el-divider>
          <div class="relation-tree-container fasdafa">
            <SimpleFamilyTreeS
              :model-value="relationTreeData"
              :current-user-id="connectBranchData.targetId"
              title="关系预览图"
              style="width: 100%; height: 100%;"
            />
          </div>
        </template>

        <div v-if="relationLoading" class="loading-container">
          <el-icon class="is-loading"><Loading /></el-icon>
          <span>正在加载关系图...</span>
        </div>

        <el-form-item>
          <el-button type="primary" @click="handleConnectBranch" :loading="connectLoading">确认接谱</el-button>
          <el-button @click="handleCloseConnectDialog">取消</el-button>
        </el-form-item>
      </el-form>
    </div>
  </el-drawer>

  <!-- 家族信息表单弹窗 -->
  <el-drawer
    v-model="dialog.visible"
    :title="dialog.title"
    :size="drawerSize"
    @close="handleCloseDialog"
  >
    <!-- 原表单 -->
    <el-form ref="dataFormRef" :model="formData" :rules="rules" label-width="150px">
      <el-form-item label="所属家族" prop="familyId">
        <el-select v-model="formData.familyId" placeholder="请选择" :disabled="dialog.readonly">
          <el-option
            v-for="item in familyOptions"
            :key="item.value"
            :label="item.label"
            :value="item.value"
          />
        </el-select>
      </el-form-item>

      <el-form-item label="姓" prop="firstName">
        <el-input
          v-model="formData.firstName"
          placeholder="姓"
          :disabled="dialog.readonly"
        />
      </el-form-item>

      <el-form-item label="名" prop="lastName">
        <el-input
          v-model="formData.lastName"
          placeholder="名"
          :disabled="dialog.readonly"
        />
      </el-form-item>

      <el-form-item label="性别" prop="gender">
        <Dict v-model="formData.gender" code="gender" :disabled="dialog.readonly" />
      </el-form-item>

      <el-form-item label="是否在世" prop="alive">
        <Dict v-model="formData.alive" code="alive" :disabled="dialog.readonly" />
      </el-form-item>

      <el-form-item v-if="dialog.type === 3 || dialog.type === 0" label="父亲" prop="parentId">
        <el-select
          v-model="formData.parentId"
          placeholder="请选择父亲"
          :disabled="dialog.readonly"
          filterable
          remote
          :remote-method="searchFather"
          :loading="fatherLoading"
          clearable
        >
          <el-option
            v-for="item in fatherOptions"
            :key="item.value"
            :label="item.label"
            :value="item.value"
          />
        </el-select>
      </el-form-item>

      <el-form-item v-if="dialog.type === 3 || dialog.type === 0" label="母亲" prop="motherId">
        <el-select v-model="formData.motherId" placeholder="请选择母亲" :disabled="dialog.readonly">
          <el-option
            v-for="item in motherOptions"
            :key="item.value"
            :label="item.label"
            :value="item.value"
          />
        </el-select>
      </el-form-item>

      <el-form-item label="昵称" prop="nickname">
        <el-input
          v-model="formData.nickname"
          placeholder="昵称"
          :disabled="dialog.readonly"
        />
      </el-form-item>
      <el-form-item label="排行" prop="sortNum">
        <el-input
          v-model.number="formData.sortNum"
          placeholder="排行（数字越小越靠前）"
          :disabled="dialog.readonly"
          type="number"
        />
      </el-form-item>

      <!-- 新增：是否开基祖字段 -->
      <el-form-item label="是否开基祖" prop="isFounder">
        <el-switch
          v-model="formData.isFounder"
          :disabled="dialog.readonly"
          :active-value="1"
          :inactive-value="0"
        />
        <span class="form-tip">开基祖将从此人开始重新计算代数</span>
      </el-form-item>

      <el-form-item label="头像照片" prop="photoUrl">
        <SingleImageUpload v-model="formData.photoUrl" :disabled="dialog.readonly" />
      </el-form-item>

      <el-form-item label="背景图" prop="backgroundPic">
        <el-select v-model="formData.backgroundPic" placeholder="请选择背景图" :disabled="dialog.readonly">
          <el-option
            v-for="item in backgroundOptions"
            :key="item.value"
            :label="item.label"
            :value="item.value"
          >
            <div style="display: flex; align-items: center;">
              <img :src="item.value" style="width: 50px; height: 30px; margin-right: 10px;" />
              <span>{{ item.label }}</span>
            </div>
          </el-option>
        </el-select>
      </el-form-item>

      <el-form-item label="字辈" prop="genation">
        <el-input
          v-model="formData.genation"
          placeholder="字辈"
          :disabled="dialog.readonly"
        />
      </el-form-item>

      <el-form-item label="字" prop="courtesyName">
        <el-input
          v-model="formData.courtesyName"
          placeholder="字"
          :disabled="dialog.readonly"
        />
      </el-form-item>

      <el-form-item label="号" prop="artName">
        <el-input
          v-model="formData.artName"
          placeholder="号"
          :disabled="dialog.readonly"
        />
      </el-form-item>

      <!-- 新增帝号字段 -->
      <el-form-item label="帝号" prop="emperorNum">
        <el-input
          v-model="formData.emperorNum"
          placeholder="帝号（如有）"
          :disabled="dialog.readonly"
        />
      </el-form-item>

      <el-form-item label="职业" prop="occupation">
        <el-input
          v-model="formData.occupation"
          placeholder="职业"
          :disabled="dialog.readonly"
        />
      </el-form-item>

      <el-form-item label="籍贯" prop="nativePlace">
        <el-input
          v-model="formData.nativePlace"
          placeholder="籍贯"
          :disabled="dialog.readonly"
        />
      </el-form-item>

      <el-form-item label="出生地" prop="birthPlace">
        <el-input
          v-model="formData.birthPlace"
          placeholder="出生地"
          :disabled="dialog.readonly"
        />
      </el-form-item>

      <el-form-item label="地址" prop="address">
        <el-input
          v-model="formData.address"
          placeholder="地址"
          :disabled="dialog.readonly"
        />
      </el-form-item>

      <el-form-item label="经度" prop="longitude">
        <el-input
          v-model="formData.longitude"
          placeholder="经度"
          :disabled="dialog.readonly"
        />
      </el-form-item>

      <el-form-item label="纬度" prop="latitude">
        <el-input
          v-model="formData.latitude"
          placeholder="纬度"
          :disabled="dialog.readonly"
        />
      </el-form-item>

      <el-form-item label="出生日期" prop="birthDate">
        <div class="date-input-group">
          <el-select
            v-model="formData.birthEra"
            style="width: 100px; margin-right: 10px;"
            :disabled="dialog.readonly"
          >
            <el-option label="公元" value="AD" />
            <el-option label="公元前" value="BC" />
          </el-select>
          <el-input
            v-model="formData.birthYear"
            placeholder="年"
            type="number"
            :disabled="dialog.readonly"
            style="width: 70px; margin-right: 10px;"
            @input="handleYearInput('birth')"
          />
          <el-input
            v-model="formData.birthMonth"
            placeholder="月"
            type="number"
            :min="1"
            :max="12"
            :disabled="dialog.readonly"
            style="width: 59px; margin-right: 10px;"
            @input="handleMonthInput('birth')"
          />
          <el-input
            v-model="formData.birthDay"
            placeholder="日"
            type="number"
            :min="1"
            :max="31"
            :disabled="dialog.readonly"
            style="width: 59px; margin-right: 10px;"
            @input="handleDayInput('birth')"
          />
          <el-input
            v-model="formData.deathHour"
            placeholder="时辰"
            type="number"
            :min="0"
            :max="23"
            :disabled="dialog.readonly"
            style="width: 70px;"
            @input="handleHourInput('death')"
          />
        </div>
      </el-form-item>

      <el-form-item label="死亡日期" prop="deathDate">
        <div class="date-input-group">
          <el-select
            v-model="formData.deathEra"
            style="width: 100px; margin-right: 10px;"
            :disabled="dialog.readonly"
          >
            <el-option label="公元" value="AD" />
            <el-option label="公元前" value="BC" />
          </el-select>
          <el-input
            v-model="formData.deathYear"
            placeholder="年"
            type="number"
            :disabled="dialog.readonly"
            style="width: 70px; margin-right: 10px;"
            @input="handleYearInput('death')"
          />
          <el-input
            v-model="formData.deathMonth"
            placeholder="月"
            type="number"
            :min="1"
            :max="12"
            :disabled="dialog.readonly"
            style="width: 59px; margin-right: 10px;"
            @input="handleMonthInput('death')"
          />
          <el-input
            v-model="formData.deathDay"
            placeholder="日"
            type="number"
            :min="1"
            :max="31"
            :disabled="dialog.readonly"
            style="width: 59px; margin-right: 10px;"
            @input="handleDayInput('death')"
          />
          <el-input
            v-model="formData.deathHour"
            placeholder="时辰"
            type="number"
            :min="0"
            :max="23"
            :disabled="dialog.readonly"
            style="width: 70px;"
            @input="handleHourInput('death')"
          />
        </div>
      </el-form-item>

      <el-form-item label="个人简介" prop="biography">
        <el-input type="textarea"
                  rows="3"
                  v-model="formData.biography"
                  placeholder="个人简介"
                  :disabled="dialog.readonly"
        />
      </el-form-item>
    </el-form>
    <template #footer>
      <div class="dialog-footer">
        <el-button v-if="dialog.type === 0 && dialog.readonly && hasAuth(['genealogy:person:edit']) && (baseFlag === 1 || formData.familyId === userFamilyId)" type="primary" @click="enableEdit">编辑</el-button>
        <el-button v-if="dialog.type === 0 && !dialog.readonly && hasAuth(['genealogy:person:edit'])" type="primary" @click="handleSubmit">确定</el-button>
        <el-button v-if="dialog.type !== 0" type="primary" @click="handleSubmit">确定</el-button>
        <el-button @click="handleCloseDialog()">取消</el-button>
      </div>
    </template>
  </el-drawer>
</template>

<script setup lang="ts">
import { ref, onMounted, onBeforeUnmount, getCurrentInstance, watch, computed, reactive } from "vue";
import * as d3 from "d3";
import type { Selection } from "d3-selection";
import type { HierarchyNode } from "d3-hierarchy";
import PersonAPI from "@/api/genealogy/person.api";
import FamilyAPI from "@/api/genealogy/family.api";
import { ElMessage, ElMessageBox } from "element-plus";
import { DeviceEnum } from "@/enums/index.js";
import { useAppStore } from "@/store/index.js";
import { getDefaultAvatar } from "@/utils/avatar";
import SingleImageUpload from "@/components/Upload/SingleImageUpload.vue";
import Dict from "@/components/Dict/index.vue";
import { hasAuth } from "@/plugins/permission";
import { useUserStore } from "@/store";
import { useRouter } from "vue-router";
import SimpleFamilyTreeS from "@/components/FamilyTree/SimpleFamilyTreeS.vue";
import { Loading } from "@element-plus/icons-vue";

const { userFamilyId,baseFlag } = useUserStore().userInfo;
const router = useRouter();
// 新增：接谱相关数据
const connectBranchOptions = ref<Array<{value: string, label: string, gender?: number, realType?: number, familyName?: string, overlapCount?: number, remark?: string}>>([]);
const branchSearchLoading = ref(false);
const connectLoading = ref(false);
const currentNodeInfo = ref<any>({});
const connectBranchData = ref({
  sourceId: '', // 当前节点ID
  targetId: '', // 目标节点ID
});
// 新增：关系图数据
const relationTreeData = ref(null);
const relationLoading = ref(false);

// 接谱对话框状态
const connectDialog = reactive({
  visible: false
});

// 新增：处理目标成员变更
async function handleTargetMemberChange(targetId) {
  if (!targetId) {
    relationTreeData.value = null;
    return;
  }

  relationLoading.value = true;
  try {
    // 调用API获取关系树数据
    const result = await PersonAPI.getTreeDataForFour(targetId);
    console.log('获取到的关系树数据:', result);
    relationTreeData.value = result;
  } catch (error) {
    console.error('获取关系树数据失败：', error);
    ElMessage.error('获取关系预览失败，请稍后重试');
    relationTreeData.value = null;
  } finally {
    relationLoading.value = false;
  }
}

// 修改：移除搜索函数，改为直接获取可接谱成员列表
async function fetchConnectableMembers(sourceId: string) {
  if (!sourceId) return;

  branchSearchLoading.value = true;
  try {
    // 调用获取可接谱成员API
    const result = await PersonAPI.searchGlobal(sourceId);

    // 处理返回结果
    const members = Array.isArray(result) ? result : [];

    // 转换为下拉选项格式 - 适应新的返回数据格式
    connectBranchOptions.value = members.map(item => ({
      value: item.targetPersonId,
      label: `${item.targetFirstName || ''}${item.targetLastName || ''}`,
      gender: undefined, // 新格式中没有性别信息
      familyName: item.targetFamilyName || '未知家谱',
      overlapCount: 0, // 新格式中没有重合代数信息，设为0
      remark: item.remark || '', // 添加备注信息
      realType: item.realType // 添加关系类型
    }));

    console.log('可接谱成员:', connectBranchOptions.value);
  } catch (error) {
    console.error('获取可接谱成员失败：', error);
    ElMessage.error('获取可接谱成员失败，请稍后重试');
    connectBranchOptions.value = [];
  } finally {
    branchSearchLoading.value = false;
  }
}

// 处理接谱提交
async function handleConnectBranch() {
  if (!connectBranchData.value.targetId) {
    ElMessage.warning('请先选择要接谱的成员');
    return;
  }

  connectLoading.value = true;
  try {
    // 构建接谱参数
    const params = {
      sourcePersonId: connectBranchData.value.sourceId,
      targetPersonId: connectBranchData.value.targetId
    };

    // 调用接谱API
    await PersonAPI.connectBranch(params);

    ElMessage.success('接谱成功，族谱已提交连接。等待对方家族审核');


    // 获取最新的节点数据，包括关联家谱信息
    try {
      const updatedPerson = await PersonAPI.getFormData(connectBranchData.value.sourceId);

      // 触发节点点击事件，通知父组件刷新数据
      emit('node-click', updatedPerson, 4);
      handleCloseConnectDialog();
    } catch (error) {
      console.error('获取更新后的节点数据失败:', error);
      // 如果获取失败，仍然触发刷新，但不包含完整的关联家谱信息
      emit('node-click', { id: connectBranchData.value.sourceId }, 4);
      handleCloseConnectDialog();
    }
  } catch (error) {
    ElMessage.error('接谱失败：' + (error.message || '未知错误'));
  } finally {
    connectLoading.value = false;
  }
}

// 处理关闭接谱对话框
function handleCloseConnectDialog() {
  connectDialog.visible = false;

  // 清空接谱相关数据
  connectBranchData.value = {
    sourceId: '',
    targetId: ''
  };
  connectBranchOptions.value = [];
  currentNodeInfo.value = {};
  relationTreeData.value = null; // 清空关系树数据
}

const appStore = useAppStore();
const drawerSize = computed(() => (appStore.device === DeviceEnum.DESKTOP ? "600px" : "90%"));

// 对话框状态接口
interface DialogState {
  visible: boolean;
  title: string;
  type: number;
  readonly: boolean;
}

// 表单数据接口
interface FormData {
  id?: string;
  firstName: string;
  lastName: string;
  gender: number;
  alive: number;
  photoUrl: string;
  motherId?: string;
  flag?: number;
  familyId?: string;
  nickname?: string;
  genation?: string;
  occupation?: string;
  birthPlace?: string;
  address?: string;
  longitude?: string;
  latitude?: string;
  birthDate?: string;
  deathDate?: string;
  biography?: string;
  type?: number;
  personId?: string;
  parentId?: string;
  nativePlace?: string;
  sortNum?: number;
  courtesyName?: string;
  artName?: string;
  backgroundPic?: string;
  isFounder?: number; // 新增：是否开基祖
  emperorNum?: string; // 新增：帝号
  familyRelationList?: Array<FamilyRelation>; // 新增：关联家谱列表
  birthYear?: string;
  birthMonth?: string;
  birthDay?: string;
  deathYear?: string;
  deathMonth?: string;
  deathDay?: string;
  birthEra?: string;
  deathEra?: string;
}

// TreeNode接口需要扩展
interface TreeNode {
  firstName: string;
  lastName: string;
  children?: TreeNode[];
  spouseList?: TreeNode[];
  parentId?: string;
  id?: string;
  collapsed?: boolean;
  familyName?: string;  // 添加缺失的familyName属性
  birthPlace?: string;
  gender?: number;
  alive?: number;
  photoUrl?: string;
  birthDate?: string;
  deathDate?: string;
  genation?: string;
  remark?: string;
  sortNum?: number; // 新增：排序号
  courtesyName?: string;
  artName?: string;
  backgroundPic?: string;
  isFounder?: number; // 新增：是否开基祖
  emperorNum?: string; // 新增：帝号
  familyRelationList?: Array<FamilyRelation>; // 新增：关联家谱列表
}

// 新增：关联家谱接口
interface FamilyRelation {
  id: string;
  sourcePersonId: string;
  sourceFamilyId: string;
  sourceFamilyName: string;
  targetFamilyName: string;
  targetFamilyId: string;
  targetPersonId: string;
  status: number;
  auditRemark?: string;
}

const props = defineProps<{
  modelValue?: TreeNode;
  treeList?: TreeNode[];  // 新增：支持多棵树
  currentUserId?: string;
  title?: string;
}>();

const emit = defineEmits<{
  (e: 'node-click', node: TreeNode, type: number): void;
  (e: 'navigate-to-family', data: {familyId: string, personId: string, familyName: string}): void;
}>();

const chartContainer = ref<HTMLElement | null>(null);
let svg: Selection<SVGSVGElement, unknown, null, undefined>;
let zoom: d3.ZoomBehavior<SVGSVGElement, unknown>;
let menu: Selection<HTMLDivElement, unknown, null, undefined>;
let currentTransform: d3.ZoomTransform | null = null; // 添加变量存储当前缩放状态

// 弹窗相关
const dialog = reactive<DialogState>({
  title: "新增成员",
  visible: false,
  type: 0,
  readonly: false
});

const dataFormRef = ref();
const familyOptions = ref<Array<{value: string, label: string}>>([]);
const motherOptions = ref<Array<{value: string, label: string}>>([]);
const fatherOptions = ref<Array<{value: string, label: string}>>([]);
const fatherLoading = ref(false);
const backgroundOptions = ref<Array<{value: string, label: string}>>([
  { value: 'https://t7.baidu.com/it/u=1956604245,3662848045&fm=193&f=GIF', label: '竹林背景' },
  { value: 'https://t7.baidu.com/it/u=1285847167,3193778276&fm=193&f=GIF', label: '山水背景' }
]);

// 初始表单数据
const initialFormData = ref<FormData>({
  id: undefined,
  firstName: "",
  lastName: "",
  gender: 1,
  alive: 1,
  photoUrl: getDefaultAvatar({ gender: 1, birthDate: "" }),
  motherId: undefined,
  flag: undefined,
  courtesyName: "",
  artName: "",
  backgroundPic: "",
  emperorNum: "", // 新增：帝号默认为空
  isFounder: 0 // 默认不是开基祖
});

// 表单数据
const formData = ref<FormData>({ ...initialFormData.value });
// 表单校验规则
const rules = reactive({
  firstName: [{ required: true, message: "请输入姓", trigger: "blur" }],
  lastName: [{ required: true, message: "请输入名", trigger: "blur" }],
  gender: [{ required: true, message: "请输入性别", trigger: "blur" }],
  alive: [{ required: true, message: "请输入是否在世", trigger: "blur" }],
});

// 新增：用于缓存原始树数据
let originalTreeData: TreeNode | TreeNode[] | null = null;
let isAncestorHidden = ref(false);

// 创建全局右键菜单容器
function createContextMenu() {
  menu = d3.select("body")
    .append("div")
    .attr("id", "d3-context-menu")
    .style("position", "fixed")
    .style("z-index", 9999)
    .style("display", "none");
}

// 计算树的深度
function getTreeDepth(node: TreeNode): number {
  if (!node.children || node.children.length === 0) {
    return 1;
  }
  return Math.max(...node.children.map(child => getTreeDepth(child))) + 1;
}

// 渲染家谱树
function renderTree(data: TreeNode | TreeNode[]) {
  // 对children按出生日期排序，递归处理
  function sortChildrenByBirthDate(node: TreeNode) {
    // 先对子节点排序
    if (Array.isArray(node.children) && node.children.length > 0) {
      node.children.sort((a, b) => {
        // 1. 先按sortNum
        if (a.sortNum !== undefined && b.sortNum !== undefined && a.sortNum !== b.sortNum) {
          return a.sortNum - b.sortNum;
        }
        if (a.sortNum !== undefined && b.sortNum === undefined) return -1;
        if (a.sortNum === undefined && b.sortNum !== undefined) return 1;
        // 2. 再按出生日期
        if (!a.birthDate && !b.birthDate) {
          // 3. 出生日期都没有时按id
          return (a.id || '').localeCompare(b.id || '');
        }
        if (!a.birthDate) return 1;
        if (!b.birthDate) return -1;
        const diff = new Date(a.birthDate).getTime() - new Date(b.birthDate).getTime();
        if (diff !== 0) return diff;
        // 4. 出生日期相同再按id
        return (a.id || '').localeCompare(b.id || '');
      });
      node.children.forEach(sortChildrenByBirthDate);
    }
    // 配偶列表也排序
    if (Array.isArray(node.spouseList) && node.spouseList.length > 0) {
      node.spouseList.sort((a, b) => (a.id || '').localeCompare(b.id || ''));
    }
  }

  if (Array.isArray(data)) {
    data.forEach(sortChildrenByBirthDate);
  } else if (data) {
    sortChildrenByBirthDate(data);
  }

  if (!chartContainer.value) return;

  // 清除之前的内容
  d3.select(chartContainer.value).selectAll("*").remove();

  // 将单一树转换为树列表
  const treeList = Array.isArray(data) ? data : [data];

  // 如果列表为空或第一个元素没有firstName，则返回
  if (treeList.length === 0 || !treeList[0].firstName) return;

  const baseWidth = 800;
  const baseHeight = 600;

  // 计算每棵树应该占用的宽度，确保每棵树都有足够的显示空间
  const treesCount = treeList.length;
  const widthScale = treesCount > 1 ? 0.8 : 1; // 当有多棵树时，适当缩小每棵树的宽度比例
  const width = baseWidth * (treesCount > 1 ? treesCount * widthScale : 1);
  const height = baseHeight;

  // 计算所有树的最大深度
  const maxDepth = Math.max(...treeList.map(tree => getTreeDepth(tree)));

  // 调整节点尺寸和间距
  const nodeWidth = 150;    // 节点宽度从120增加到150
  const nodeHeight = 300;   // 节点高度从260增加到300
  const spouseSpacing = 180;  // 配偶节点间距从150增加到180
  const levelSpacing = 350;   // 层级间距从320增加到350
  const siblingSpacing = treesCount > 1 ? 160 : 180; // 兄弟节点间距增加
  const treeSpacing = width * 0.05;    // 树之间的间距

  // 创建SVG容器
  svg = d3.select(chartContainer.value)
    .append("svg")
    .attr("width", "100%")
    .attr("height", "100%")
    .attr("viewBox", `0 0 ${width} ${height}`)
    .style("background-color", "#f9f6ef"); // 添加古纸风格背景色

  const g = svg.append("g");

  // 添加标题
  svg.append("text")
    .attr("x", width / 2)
    .attr("y", 30)
    .attr("text-anchor", "middle")
    .attr("font-family", "'SimSun', 'FangSong', serif")
    .attr("font-size", "24px")
    .attr("font-weight", "bold")
    .attr("fill", "#8B4513")
    .text(() => {
      return props.title || (treesCount > 1 ? "全族谱" : "家族谱系图");
    });

  // 添加页脚
  svg.append("text")
    .attr("x", width / 2)
    .attr("y", height - 20)
    .attr("text-anchor", "middle")
    .attr("font-family", "'KaiTi', 'SimKai', serif")
    .attr("font-size", "12px")
    .attr("fill", "#8B4513")
    .attr("opacity", 0.7)
    .text("慎终追远 民德归厚");

  // 添加左右装饰
  svg.append("text")
    .attr("x", 20)
    .attr("y", height / 6)
    .attr("text-anchor", "middle")
    .attr("transform", `rotate(-90, 20, ${height / 2})`)
    .attr("font-family", "'KaiTi', 'SimKai', serif")
    .attr("font-size", "14px")
    .attr("fill", "#8B4513")
    .attr("opacity", 0.5)
    .text("忠孝传家");

  svg.append("text")
    .attr("x", width - 20)
    .attr("y", height / 6)
    .attr("text-anchor", "middle")
    .attr("transform", `rotate(90, ${width - 20}, ${height / 2})`)
    .attr("font-family", "'KaiTi', 'SimKai', serif")
    .attr("font-size", "14px")
    .attr("fill", "#8B4513")
    .attr("opacity", 0.5)
    .text("礼义继世");

  // 添加缩放功能
  zoom = d3.zoom<SVGSVGElement, unknown>()
    .scaleExtent([0.01, 1.2])
    .on("zoom", (event) => {
      g.attr("transform", event.transform);
      currentTransform = event.transform;
    });

  svg.call(zoom);

  // 自动计算合适的初始缩放比例，确保所有树都能在视图中显示
  const initialScale = treesCount > 1 ? Math.max(0.5, 1 / (treesCount * 0.7)) : 0.9;
  const initialTransform = d3.zoomIdentity.scale(initialScale).translate(width * 0.1, height * 0.1);

  if (currentTransform) {
    svg.call(zoom.transform, currentTransform);
  } else {
    // 如果是首次渲染或没有保存的变换，使用计算的初始变换
    svg.call(zoom.transform, initialTransform);
    currentTransform = initialTransform;
  }

  // 计算每棵树实际占用的宽度
  const singleTreeWidth = (width - (treeSpacing * (treesCount - 1))) / treesCount;
  // 在 renderTree 函数顶部定义
  const spousePositionMap = new Map();
  // 为每棵树创建一个组
  treeList.forEach((treeData, treeIndex) => {
    // 创建树布局
    const treeLayout = d3.tree<TreeNode>()
      .size([singleTreeWidth * 0.8, height - 120]) // 留出顶部和底部的空间
      .nodeSize([siblingSpacing, levelSpacing])
      .separation((a, b) => {
        const aSpouses = a.data.spouseList ? a.data.spouseList.length : 0;
        const bSpouses = b.data.spouseList ? b.data.spouseList.length : 0;
        const totalSpouseWidth = (aSpouses + bSpouses) * spouseSpacing / (treesCount > 1 ? treesCount * 0.7 : 1);
        return 1 + (totalSpouseWidth / siblingSpacing);
      });

    const root = d3.hierarchy(treeData);
    treeLayout(root);

    // 计算此树的x位置，考虑树间距
    const treeXPosition = treeIndex * (singleTreeWidth + treeSpacing);

    // 创建每棵树的容器
    const treeG = g.append("g")
      .attr("class", `tree-${treeIndex}`)
      .attr("transform", `translate(${treeXPosition}, 0)`);

    // 计算树的整体宽度，用于居中显示
    const treeWidth = d3.max(root.descendants(), d => d.x) || 0;
    const treeHeight = d3.max(root.descendants(), d => d.y) || 0;

    // 计算每棵树的居中偏移量
    const xOffset = (singleTreeWidth - treeWidth) / 2;
    const yOffset = 80; // 为顶部标题预留更多空间

    // 递归检查节点是否应该显示
    function shouldShowNode(node: d3.HierarchyNode<TreeNode>): boolean {
      if (!node.parent) return true;
      // 检查节点本身是否被收缩
      if (node.data.collapsed) return false;
      // 检查父节点是否被收缩
      if (node.parent.data.collapsed) return false;
      return shouldShowNode(node.parent);
    }

    // 检查是否应该显示收缩按钮（即使节点本身被收缩也显示按钮）
    function shouldShowCollapseButton(node: d3.HierarchyNode<TreeNode>): boolean {
      if (!node.parent) return true;
      // 只检查父节点是否被收缩，不检查自己
      if (node.parent.data.collapsed) return false;
      return shouldShowCollapseButton(node.parent);
    }

    // 递归检查连接线是否应该显示
    function shouldShowLink(link: d3.HierarchyLink<TreeNode>): boolean {
      // 即使目标节点被收缩，也显示连接线
      if (link.target.data.collapsed) {
        // 对于收缩的节点，只检查其父节点路径是否可见
        return shouldShowCollapseButton(link.target);
      }
      return shouldShowNode(link.source) && shouldShowNode(link.target);
    }

    // 绘制连接线
    treeG.selectAll(".link")
      .data(root.links().filter(shouldShowLink))
      .enter()
      .append("path")
      .attr("class", "link")
      .attr("d", d => {
        const sourceX = d.source.x + xOffset;
        const sourceY = d.source.y + yOffset;
        const targetX = d.target.x + xOffset;
        const targetY = d.target.y + yOffset;

        // 对于收缩的节点，连接线只绘制到收缩按钮的位置，但保持形状不变
        if (d.target.data.collapsed) {
          // 收缩按钮位于节点上方15px处
          const buttonY = targetY - nodeHeight/2 - 15;

          // 计算正常连接线的中间点Y坐标
          const midY = (sourceY + targetY) / 2;

          // 如果中间点在按钮之上，正常绘制到中间点，然后到按钮
          if (midY <= buttonY) {
            return `M${sourceX},${sourceY} L${sourceX},${midY} L${targetX},${midY} L${targetX},${buttonY}`;
          }
          // 否则将中间点调整到源点和按钮之间
          else {
            const adjustedMidY = (sourceY + buttonY) / 2;
            return `M${sourceX},${sourceY} L${sourceX},${adjustedMidY} L${targetX},${adjustedMidY} L${targetX},${buttonY}`;
          }
        }

        return `M${sourceX},${sourceY} L${sourceX},${(sourceY + targetY) / 2} L${targetX},${(sourceY + targetY) / 2} L${targetX},${targetY}`;
      })
      .attr("fill", "none")
      .attr("stroke", "#8B4513") // 更改为棕色线条
      .attr("stroke-width", 2)
      .attr("stroke-dasharray", "5,3"); // 添加虚线效果

    // 预先创建夫妻连接线
    root.descendants().filter(shouldShowNode).forEach(d => {
      if (d.data.spouseList && d.data.spouseList.length > 0) {
        const spouses = d.data.spouseList;
        const nodeX = d.x + xOffset;
        const nodeY = d.y + yOffset;

        spouses.forEach((spouse, i) => {
          treeG.append("line")
            .attr("class", "spouse-link")
            .attr("x1", nodeX)
            .attr("y1", nodeY)
            .attr("x2", nodeX + (i + 1) * spouseSpacing)
            .attr("y2", nodeY)
            .attr("stroke", "#8B4513")
            .attr("stroke-width", 1.5)
            .attr("stroke-dasharray", "3,3");
        });
      }
    });

    // 为收缩的节点单独创建收缩按钮组
    const collapseButtonGroups = treeG.selectAll(".collapse-button-group")
      .data(root.descendants().filter(d => {
        // 显示所有应该有收缩按钮的节点的按钮，包括自身已收缩的节点
        return d.data.collapsed && shouldShowCollapseButton(d);
      }))
      .enter()
      .append("g")
      .attr("class", "collapse-button-group")
      .attr("transform", d => `translate(${d.x + xOffset},${d.y + yOffset})`);

    // 为收缩的节点添加收缩按钮
    collapseButtonGroups.append("circle")
      .attr("class", "node-collapse-button")
      .attr("cx", 0)
      .attr("cy", -nodeHeight/2 - 15)
      .attr("r", 12)
      .attr("fill", "#f9f6ef")
      .attr("stroke", "#8B4513")
      .attr("stroke-width", 2)
      .style("cursor", "pointer")
      .on("click", (event, d) => {
        event.stopPropagation();
        d.data.collapsed = !d.data.collapsed;

        // 递归设置所有子节点的collapsed状态
        function setChildrenCollapsedState(node: d3.HierarchyNode<TreeNode>, collapsed: boolean) {
          if (node.children) {
            node.children.forEach(child => {
              child.data.collapsed = collapsed;
              setChildrenCollapsedState(child, collapsed);
            });
          }
        }

        setChildrenCollapsedState(d, d.data.collapsed);
        renderTree(data);
      });

    // 为收缩的节点添加收缩图标 - 改为中国风图案
    collapseButtonGroups.append("text")
      .attr("class", "node-collapse-icon")
      .attr("x", 0)
      .attr("y", -nodeHeight/2 - 12)
      .attr("text-anchor", "middle")
      .attr("dy", "0.3em")
      .attr("fill", "#8B4513")
      .style("font-family", "'SimSun', serif")
      .style("font-size", "16px")
      .style("pointer-events", "none")
      .text("展");

    // 添加节点 - 以下部分会重复出现在单一树的渲染中
    const nodes = treeG.selectAll(".node")
      .data(root.descendants().filter(shouldShowNode))
      .enter()
      .append("g")
      .attr("class", "node")
      .attr("transform", d => `translate(${d.x + xOffset},${d.y + yOffset})`);

    // 添加节点头部收缩按钮
    nodes.append("circle")
      .attr("class", "node-collapse-button")
      .attr("cx", 0)
      .attr("cy", -nodeHeight/2 - 15)
      .attr("r", 12)
      .attr("fill", "#f9f6ef")
      .attr("stroke", "#8B4513")
      .attr("stroke-width", 2)
      .style("cursor", "pointer")
      .on("click", (event, d) => {
        event.stopPropagation();

        // 递归设置所有子节点的collapsed状态
        function setChildrenCollapsedState(node: d3.HierarchyNode<TreeNode>, collapsed: boolean) {
          if (node.children) {
            node.children.forEach(child => {
              child.data.collapsed = collapsed;
              setChildrenCollapsedState(child, collapsed);
            });
          }
        }

        d.data.collapsed = !d.data.collapsed;
        setChildrenCollapsedState(d, d.data.collapsed);
        renderTree(data);
      });

    // 添加节点头部收缩图标 - 改为中国风图案
    nodes.append("text")
      .attr("class", "node-collapse-icon")
      .attr("x", 0)
      .attr("y", -nodeHeight/2 - 12)
      .attr("text-anchor", "middle")
      .attr("dy", "0.3em")
      .attr("fill", "#8B4513")
      .style("font-family", "'SimSun', serif")
      .style("font-size", "16px")
      .style("pointer-events", "none")
      .text("收");

    // 节点矩形
    nodes.append("rect")
      .attr("width", nodeWidth)
      .attr("height", nodeHeight)
      .attr("x", -nodeWidth/2)
      .attr("y", -nodeHeight/2)
      .attr("rx", 8)
      .attr("data-user-id", d => d.data.id) // 添加这一行
      .attr("fill", d => {
        if (d.data.alive === 0) {
          return "#e0e0e0"; // 过世人员的灰色背景
        }
        // 如果有帝号，使用原来当前用户的背景颜色
        if (d.data.emperorNum) {
          return "#fff7e6"; // 皇帝用原来当前用户的背景色
        }
        // 女儿：gender=2 且不是配偶节点（即父节点的spouseList不包含自己）
        if (d.data.gender === 2 && (!d.parent || !(d.parent.data.spouseList && d.parent.data.spouseList.some(sp => sp.id === d.data.id)))) {
          return "#b2f7ef"; // 女儿用淡青色
        }
        return d.data.id === props.currentUserId ? "#fff7e6" : d.data.gender === 1 ? "#e6f2ff" : "#fff0f5";
      })
      .attr("stroke", d => {
        // 如果有帝号，使用金色边框
        if (d.data.emperorNum) {
          return "#ff9900"; // 金色边框，使用原来当前用户的颜色
        }
        // 当前用户使用红色边框
        if (d.data.id === props.currentUserId) {
          return "#FF0000"; // 红色边框
        }
        // 女儿：gender=2 且不是配偶节点
        if (d.data.gender === 2 && (!d.parent || !(d.parent.data.spouseList && d.parent.data.spouseList.some(sp => sp.id === d.data.id)))) {
          return "#1bcaca"; // 女儿边框用深一点的青色
        }
        return d.data.gender === 1 ? "#4169E1" : "#C71585";
      }) // 当前用户使用红色边框
      .attr("stroke-width", d => {
        // 如果有帝号，使用更粗的边框
        if (d.data.emperorNum) {
          return 4;
        }
        return d.data.id === props.currentUserId ? 4 : 2;
      })
      .style("filter", d => {
        // 如果有帝号，添加金色光晕效果
        if (d.data.emperorNum) {
          return "drop-shadow(0px 0px 8px rgba(255, 153, 0, 0.5))"; // 使用原来当前用户的光晕效果
        }
        if (d.data.id === props.currentUserId) {
          return "drop-shadow(0px 0px 8px rgba(255, 0, 0, 0.5))"; // 为当前用户添加红色发光效果
        }
        return "drop-shadow(0px 2px 3px rgba(0, 0, 0, 0.2))";
      })
      .on("click", (event, d) => {
        event.stopPropagation();
        showContextMenu(event, d);
      })
      .on("contextmenu", (event, d) => {
        event.preventDefault();
        showContextMenu(event, d);
      });

    // 添加关联家谱指示器
    nodes.append("g")
      .attr("class", "family-relation-indicator")
      .attr("transform", d => `translate(${nodeWidth/2 - 35}, ${nodeHeight/2 - 35})`)
      .each(function(d) {
        // 只有存在关联家谱时才显示指示器
        if (d.data.familyRelationList && d.data.familyRelationList.length > 0) {
          // 创建中国结效果
          const indicatorGroup = d3.select(this);

          // 背景圆
          indicatorGroup.append("circle")
            .attr("r", 15)
            .attr("cx", 15)
            .attr("cy", 15)
            .attr("fill", "#c53030")
            .attr("stroke", "#8b0000")
            .attr("stroke-width", 1.5)
            .attr("filter", "drop-shadow(0px 2px 3px rgba(0, 0, 0, 0.3))");

          // 中国结外环
          indicatorGroup.append("path")
            .attr("d", `M15,3
                        C21,3 27,9 27,15
                        C27,21 21,27 15,27
                        C9,27 3,21 3,15
                        C3,9 9,3 15,3
                        Z`)
            .attr("fill", "none")
            .attr("stroke", "#ffcc00")
            .attr("stroke-width", 1.5)
            .attr("stroke-dasharray", "3,2");

          // 中国结内部结构 - 横线
          indicatorGroup.append("path")
            .attr("d", "M8,15 H22")
            .attr("fill", "none")
            .attr("stroke", "#ffcc00")
            .attr("stroke-width", 1.5);

          // 中国结内部结构 - 竖线
          indicatorGroup.append("path")
            .attr("d", "M15,8 V22")
            .attr("fill", "none")
            .attr("stroke", "#ffcc00")
            .attr("stroke-width", 1.5);

          // 中国结内部结构 - 左上到右下
          indicatorGroup.append("path")
            .attr("d", "M9,9 L21,21")
            .attr("fill", "none")
            .attr("stroke", "#ffcc00")
            .attr("stroke-width", 1.5);

          // 中国结内部结构 - 右上到左下
          indicatorGroup.append("path")
            .attr("d", "M21,9 L9,21")
            .attr("fill", "none")
            .attr("stroke", "#ffcc00")
            .attr("stroke-width", 1.5);

          // 中心点
          indicatorGroup.append("circle")
            .attr("r", 4)
            .attr("cx", 15)
            .attr("cy", 15)
            .attr("fill", "#ffcc00");
        }
      })
      .style("cursor", "pointer")
      .on("click", (event, d) => {
        event.stopPropagation();
        handleGotoRelatedFamily(d.data);
      });

    // 添加背景图
    nodes.append("image")
      .attr("xlink:href", d => d.data.backgroundPic || "")
      .attr("x", -nodeWidth/2)
      .attr("y", -nodeHeight/2)
      .attr("width", nodeWidth)
      .attr("height", nodeHeight)
      .attr("rx", 8)
      .attr("preserveAspectRatio", "xMidYMid slice")
      .attr("opacity", d => d.data.backgroundPic ? 0.3 : 0)
      .style("pointer-events", "none");

    // 添加装饰边框 - 同样增强当前用户的边框效果
    nodes.append("rect")
      .attr("width", nodeWidth - 6)
      .attr("height", nodeHeight - 6)
      .attr("x", -nodeWidth/2 + 3)
      .attr("y", -nodeHeight/2 + 3)
      .attr("rx", 6)
      .attr("fill", "none")
      .attr("stroke", d => {
        // 如果有帝号，使用金色边框
        if (d.data.emperorNum) {
          return "#ff9900"; // 金色边框，使用原来当前用户的颜色
        }
        // 当前用户使用红色边框
        if (d.data.id === props.currentUserId) {
          return "#FF0000"; // 红色边框
        }
        // 女儿：gender=2 且不是配偶节点
        if (d.data.gender === 2 && (!d.parent || !(d.parent.data.spouseList && d.parent.data.spouseList.some(sp => sp.id === d.data.id)))) {
          return "#1bcaca"; // 女儿边框用深一点的青色
        }
        return d.data.gender === 1 ? "#4169E1" : "#C71585";
      })
      .attr("stroke-width", d => {
        // 如果有帝号，使用更粗的边框
        if (d.data.emperorNum) {
          return 2;
        }
        return d.data.id === props.currentUserId ? 2 : 1;
      })
      .attr("stroke-dasharray", d => {
        // 如果有帝号，使用不同的虚线样式
        if (d.data.emperorNum) {
          return "7,3";
        }
        return d.data.id === props.currentUserId ? "5,3" : "3,3";
      })
      .style("pointer-events", "none");

    // 添加"第几代"角标 - 位置移到中间
    nodes.append("g")
      .attr("class", "generation-badge")
      .attr("transform", d => `translate(0, ${-nodeHeight/2 + 6})`)
      .each(function(d) {
        // 角标文字，直接添加文字，不添加背景矩形
        d3.select(this).append("text")
          .attr("x", 0) // 居中
          .attr("y", 14)
          .attr("text-anchor", "middle")
          .attr("font-size", "12px")
          .attr("font-family", "'KaiTi', 'SimKai', serif")
          .attr("fill", "#b97a00")
          .text(d => {
            // 计算代数，考虑开基祖情况
            const genInfo = calculateGeneration(d);

            // 只有当代数大于0时，才显示代数信息
            if (genInfo.generation > 0) {
              // 如果是第1代，显示为"始祖"
              if (genInfo.generation === 1) {
                return `${d.depth + 1}世 ${genInfo.founderName}始祖`;
              } else {
                return `${d.depth + 1}世 ${genInfo.founderName}第${genInfo.generation}代`;
              }
            } else {
              // 没有代数时，只显示世系信息
              return `${d.depth + 1}世`;
            }
          });
      });

    // 节点图片 - 放在顶部，缩小并下移
    nodes.append("image")
      .attr("xlink:href", d => d.data.photoUrl || "https://s2.loli.net/2023/05/24/yNsxFC8rLHMZQcK.jpg")
      .attr("x", -35)
      .attr("y", -nodeHeight/2 + 30) // 从10改为30，下移20px
      .attr("width", 70) // 从80改为70
      .attr("height", 70) // 从80改为70
      .style("filter", d => d.data.alive === 1 ? "none" : "grayscale(100%)")
      .on("click", (event, d) => showContextMenu(event, d));

    // 节点姓名文字 - 放在图片下方中间位置，调整位置
    nodes.append("text")
      .text(d => {
        if (!d.data.firstName || !d.data.lastName) return '';
        let nameText = `${d.data.firstName}${d.data.lastName}`;
        // 如果有字辈，添加到名字右边
        if (d.data.genation) {
          nameText += ` (${d.data.genation})`;
        }
        return nameText;
      })
      .attr("text-anchor", "middle")
      .attr("x", 0)
      .attr("y", -nodeHeight/2 + 120) // 从110改为120
      .style("font-family", "'FangSong', 'SimSun', serif") // 使用仿宋或宋体字体
      .style("font-size", "16px")
      .style("font-weight", "bold")
      .style("pointer-events", "none");

    // 添加同代人数信息 - 默认不显示，只在需要时动态添加
    nodes.append("text")
      .attr("class", "same-generation-info")
      .attr("text-anchor", "middle")
      .attr("x", 0)
      .attr("y", -nodeHeight/2 + 140)
      .style("font-family", "'KaiTi', 'SimKai', serif")
      .style("font-size", "14px")
      .style("fill", "#b97a00")
      .style("font-weight", "bold")
      .style("pointer-events", "none")
      .style("opacity", 0) // 默认隐藏
      .text(d => {
        const sameGenCount = countSameGenerationMembers(d);
        return `同代共${sameGenCount}人`;
      });

    // 添加排行信息
    nodes.append("text")
      .text(d => {
        let text = "";
        if (d.data.sortNum) {
          text += `排行: ${d.data.sortNum}`;
        }
        if (d.data.emperorNum) {
          text += text ? ` 帝号: ${d.data.emperorNum}` : `帝号: ${d.data.emperorNum}`;
        }
        return text;
      })
      .attr("text-anchor", "middle")
      .attr("x", 0)
      .attr("y", nodeHeight/2 - 120)
      .style("font-family", "'KaiTi', 'SimKai', serif")
      .style("font-size", "14px")
      .style("pointer-events", "none");

    // 添加生卒年信息 - 调整位置
    nodes.append("text")
      .text(d => {
        let lifeInfo = "";

        // 提取年份信息
        const extractYear = (dateStr) => {
          if (!dateStr) return null;
          // 支持负数年份（公元前）
          const match = dateStr.match(/(-?\d{1,4})/);
          return match ? match[1] : null;
        };

        // 格式化年份显示
        const formatYear = (year) => {
          if (!year) return "";
          const yearNum = parseInt(year);
          if (yearNum < 0) {
            return `前${Math.abs(yearNum)}`;
          }
          return `${yearNum}`;
        };

        const birthYear = extractYear(d.data.birthDate);
        const deathYear = extractYear(d.data.deathDate);

        if (birthYear) {
          lifeInfo += formatYear(birthYear);
          if (d.data.alive === 0 && deathYear) {
            lifeInfo += `-${formatYear(deathYear)}`;
          } else if (d.data.alive === 0) {
            lifeInfo += "-?";
          }
        }

        // 返回生卒信息，如果没有则返回空字符串
        if (lifeInfo) {
          if (d.data.alive === 0) {
            return `生卒: ${lifeInfo}`;
          } else {
            return `生: ${lifeInfo}`;
          }
        }
        return "";
      })
      .attr("text-anchor", "middle")
      .attr("x", 0)
      .attr("y", nodeHeight/2 - 140)
      .style("font-family", "'KaiTi', 'SimKai', serif")
      .style("font-size", "14px")
      .style("pointer-events", "none");

    // 添加职业信息
    nodes.append("text")
      .text(d => d.data.occupation ? `职业: ${d.data.occupation}` : "")
      .attr("text-anchor", "middle")
      .attr("x", 0)
      .attr("y", nodeHeight/2 - 100)
      .style("font-family", "'KaiTi', 'SimKai', serif")
      .style("font-size", "14px")
      .style("pointer-events", "none");

    // 添加籍贯信息
    nodes.append("text")
      .text(d => d.data.nativePlace ? `籍贯: ${d.data.nativePlace}` : "")
      .attr("text-anchor", "middle")
      .attr("x", 0)
      .attr("y", nodeHeight/2 - 80)
      .style("font-family", "'KaiTi', 'SimKai', serif")
      .style("font-size", "14px")
      .style("pointer-events", "none");

    // 添加出生地信息
    nodes.append("text")
      .text(d => d.data.birthPlace ? `出生: ${d.data.birthPlace}` : "")
      .attr("text-anchor", "middle")
      .attr("x", 0)
      .attr("y", nodeHeight/2 - 60)
      .style("font-family", "'KaiTi', 'SimKai', serif")
      .style("font-size", "14px")
      .style("pointer-events", "none");

    // 添加字号信息
    nodes.append("text")
      .text(d => {
        let info = "";
        if (d.data.courtesyName) info += `字: ${d.data.courtesyName}`;
        if (d.data.artName) {
          if (info) info += " ";
          info += `号: ${d.data.artName}`;
        }
        return info;
      })
      .attr("text-anchor", "middle")
      .attr("x", 0)
      .attr("y", nodeHeight/2 - 40)
      .style("font-family", "'KaiTi', 'SimKai', serif")
      .style("font-size", "14px")
      .style("pointer-events", "none");

    // 添加备注信息
    nodes.append("text")
      .text(d => d.data.remark ? `称呼: ${d.data.remark}` : "")
      .attr("text-anchor", "middle")
      .attr("x", 0)
      .attr("y", nodeHeight/2 - 20)
      .style("font-family", "'KaiTi', 'SimKai', serif")
      .style("font-size", "14px")
      .style("pointer-events", "none");

    // 绘制配偶节点 - 水平排列
    nodes.each(function(d) {
      const node = d3.select(this);
      const spouses = d.data.spouseList || [];

      spouses.forEach((spouse, i) => {
        const spouseGroup = node.append("g")
          .attr("class", "spouse-node")
          .attr("transform", `translate(${(i + 1) * spouseSpacing},0)`);

        spouseGroup.append("rect")
          .attr("width", nodeWidth)
          .attr("height", nodeHeight)
          .attr("x", -nodeWidth/2)
          .attr("y", -nodeHeight/2)
          .attr("rx", 8)
          .attr("fill", () => {
            if (spouse.alive === 0) {
              return "#e0e0e0"; // 过世人员的灰色背景
            }
            // 如果有帝号，使用原来当前用户的背景颜色
            if (spouse.emperorNum) {
              return "#fff7e6"; // 皇帝用原来当前用户的背景色
            }
            return spouse.gender === 1 ?  "#e6f2ff" : "#fff0f5";
          })
          .attr("stroke", () => {
            // 如果有帝号，使用金色边框
            if (spouse.emperorNum) {
              return "#ff9900"; // 金色边框，使用原来当前用户的颜色
            }
            // 当前用户使用红色边框
            if (spouse.id === props.currentUserId) {
              return "#FF0000"; // 红色边框
            }
            return spouse.gender === 1 ? "#4169E1" : "#C71585"; // 根据性别设置边框颜色
          })
          .attr("stroke-width", () => {
            // 如果有帝号或是当前用户，使用更粗的边框
            if (spouse.emperorNum || spouse.id === props.currentUserId) {
              return 4;
            }
            return 2;
          })
          .style("filter", () => {
            // 如果有帝号，添加金色光晕
            if (spouse.emperorNum) {
              return "drop-shadow(0px 0px 8px rgba(255, 153, 0, 0.5))"; // 使用原来当前用户的光晕效果
            }
            // 当前用户添加红色光晕
            if (spouse.id === props.currentUserId) {
              return "drop-shadow(0px 0px 8px rgba(255, 0, 0, 0.5))";
            }
            return "drop-shadow(0px 2px 3px rgba(0, 0, 0, 0.2))";
          })
          .on("click", (event) => {
            // 创建一个新的节点对象，包含配偶的信息
            const spouseNode = {
              ...spouse,
              parentId: d.data.id // 设置父节点ID为当前节点
            };
            // 创建一个新的HierarchyNode对象
            const spouseHierarchyNode = {
              data: spouseNode,
              depth: d.depth,
              height: d.height,
              parent: d,
              children: []
            };
            showContextMenu(event, spouseHierarchyNode);
          });

        // 添加配偶背景图
        spouseGroup.append("image")
          .attr("xlink:href", spouse.backgroundPic || "")
          .attr("x", -nodeWidth/2)
          .attr("y", -nodeHeight/2)
          .attr("width", nodeWidth)
          .attr("height", nodeHeight)
          .attr("rx", 8)
          .attr("preserveAspectRatio", "xMidYMid slice")
          .attr("opacity", spouse.backgroundPic ? 0.3 : 0)
          .style("pointer-events", "none");

        // 添加装饰边框
        spouseGroup.append("rect")
          .attr("width", nodeWidth - 6)
          .attr("height", nodeHeight - 6)
          .attr("x", -nodeWidth/2 + 3)
          .attr("y", -nodeHeight/2 + 3)
          .attr("rx", 6)
          .attr("fill", "none")
          .attr("stroke", () => {
            // 如果有帝号，使用金色边框
            if (spouse.emperorNum) {
              return "#ff9900"; // 金色边框，使用原来当前用户的颜色
            }
            // 当前用户使用红色边框
            if (spouse.id === props.currentUserId) {
              return "#FF0000"; // 红色边框
            }
            return spouse.gender === 1 ? "#4169E1" : "#C71585";
          })
          .attr("stroke-width", () => {
            // 如果有帝号或是当前用户，使用更粗的边框
            if (spouse.emperorNum || spouse.id === props.currentUserId) {
              return 2;
            }
            return 1;
          })
          .attr("stroke-dasharray", () => {
            // 如果有帝号，使用不同的虚线样式
            if (spouse.emperorNum) {
              return "7,3";
            }
            // 当前用户使用不同的虚线样式
            if (spouse.id === props.currentUserId) {
              return "5,3";
            }
            return "3,3"; // 默认虚线样式
          })
          .style("pointer-events", "none");

        // 为配偶节点添加"第几代"角标 - 位置移到中间
        spouseGroup.append("g")
          .attr("class", "generation-badge")
          .attr("transform", `translate(0, ${-nodeHeight/2 + 6})`)
          .each(function() {
            // 角标文字，直接添加文字，不添加背景矩形
            d3.select(this).append("text")
              .attr("x", 0) // 居中
              .attr("y", 14)
              .attr("text-anchor", "middle")
              .attr("font-size", "12px")
              .attr("font-family", "'KaiTi', 'SimKai', serif")
              .attr("fill", "#b97a00")
              .text(() => {
                // 计算代数，考虑开基祖情况
                const genInfo = calculateGeneration(d);

                // 只有当代数大于0时，才显示代数信息
                if (genInfo.generation > 0) {
                  // 如果是第1代，显示为"始祖"
                  if (genInfo.generation === 1) {
                    return `${d.depth + 1}世 ${genInfo.founderName}始祖`;
                  } else {
                    return `${d.depth + 1}世 ${genInfo.founderName}第${genInfo.generation}代`;
                  }
                } else {
                  // 没有代数时，只显示世系信息
                  return `${d.depth + 1}世`;
                }
              });
          });

        // 添加配偶图片 - 改为方形放在顶部，缩小并下移
        spouseGroup.append("image")
          .attr("xlink:href", spouse.photoUrl || "https://s2.loli.net/2023/05/24/yNsxFC8rLHMZQcK.jpg")
          .attr("x", -35)
          .attr("y", -nodeHeight/2 + 30) // 从10改为30，下移20px
          .attr("width", 70) // 从80改为70
          .attr("height", 70) // 从80改为70
          .style("filter", spouse.alive === 1 ? "none" : "grayscale(100%)")
          .on("click", (event) => {
            // 创建一个新的节点对象，包含配偶的信息
            const spouseNode = {
              ...spouse,
              parentId: d.data.id // 设置父节点ID为当前节点
            };
            // 创建一个新的HierarchyNode对象
            const spouseHierarchyNode = {
              data: spouseNode,
              depth: d.depth,
              height: d.height,
              parent: d,
              children: []
            };
            showContextMenu(event, spouseHierarchyNode);
          });

        // 添加配偶姓名，调整位置
        spouseGroup.append("text")
          .text(() => {
            let nameText = `${spouse.firstName}${spouse.lastName}`;
            // 如果有字辈，添加到名字右边
            if (spouse.genation) {
              nameText += ` (${spouse.genation})`;
            }
            return nameText;
          })
          .attr("text-anchor", "middle")
          .attr("x", 0)
          .attr("y", -nodeHeight/2 + 120) // 从110改为120
          .style("font-family", "'FangSong', 'SimSun', serif")
          .style("font-size", "16px")
          .style("font-weight", "bold")
          .style("pointer-events", "none");

        // 添加配偶排行信息
        spouseGroup.append("text")
          .text(() => {
            let text = "";
            if (spouse.sortNum) {
              text += `排行: ${spouse.sortNum}`;
            }
            if (spouse.emperorNum) {
              text += text ? ` 帝号: ${spouse.emperorNum}` : `帝号: ${spouse.emperorNum}`;
            }
            return text;
          })
          .attr("text-anchor", "middle")
          .attr("x", 0)
          .attr("y", nodeHeight/2 - 120)
          .style("font-family", "'KaiTi', 'SimKai', serif")
          .style("font-size", "14px")
          .style("pointer-events", "none");

        // 添加配偶职业信息 - 新增
        spouseGroup.append("text")
          .text(() => spouse.occupation ? `职业: ${spouse.occupation}` : "")
          .attr("text-anchor", "middle")
          .attr("x", 0)
          .attr("y", nodeHeight/2 - 100)
          .style("font-family", "'KaiTi', 'SimKai', serif")
          .style("font-size", "14px")
          .style("pointer-events", "none");

        // 添加配偶出生地信息 - 新增
        spouseGroup.append("text")
          .text(() => spouse.birthPlace ? `出生: ${spouse.birthPlace}` : "")
          .attr("text-anchor", "middle")
          .attr("x", 0)
          .attr("y", nodeHeight/2 - 80)
          .style("font-family", "'KaiTi', 'SimKai', serif")
          .style("font-size", "14px")
          .style("pointer-events", "none");

        // 添加配偶籍贯信息
        spouseGroup.append("text")
          .text(() => {
            return spouse.nativePlace ? `籍贯: ${spouse.nativePlace}` : "";
          })
          .attr("text-anchor", "middle")
          .attr("x", 0)
          .attr("y", nodeHeight/2 - 60)
          .style("font-family", "'KaiTi', 'SimKai', serif")
          .style("font-size", "14px")
          .style("pointer-events", "none");

        // 添加配偶字号信息 - 作为信息行显示 - 调整位置
        spouseGroup.append("text")
          .text(() => {
            let info = "";
            if (spouse.courtesyName) info += `字: ${spouse.courtesyName}`;
            if (spouse.artName) {
              if (info) info += " ";
              info += `号: ${spouse.artName}`;
            }
            return info;
          })
          .attr("text-anchor", "middle")
          .attr("x", 0)
          .attr("y", nodeHeight/2 - 40)
          .style("font-family", "'KaiTi', 'SimKai', serif")
          .style("font-size", "14px")
          .style("pointer-events", "none");

        // 添加配偶备注信息 - 移至最底部
        spouseGroup.append("text")
          .text(() => spouse.remark ? `称呼: ${spouse.remark}` : "")
          .attr("text-anchor", "middle")
          .attr("x", 0)
          .attr("y", nodeHeight/2 - 20)
          .style("font-family", "'KaiTi', 'SimKai', serif")
          .style("font-size", "14px")
          .style("pointer-events", "none");

        // 添加配偶生卒年
        spouseGroup.append("text")
          .text(() => {
            let lifeInfo = "";

            // 提取年份信息
            const extractYear = (dateStr) => {
              if (!dateStr) return null;
              // 支持负数年份（公元前）
              const match = dateStr.match(/(-?\d{1,4})/);
              return match ? match[1] : null;
            };

            // 格式化年份显示
            const formatYear = (year) => {
              if (!year) return "";
              const yearNum = parseInt(year);
              if (yearNum < 0) {
                return `前${Math.abs(yearNum)}`;
              }
              return `${yearNum}`;
            };

            const birthYear = extractYear(spouse.birthDate);
            const deathYear = extractYear(spouse.deathDate);

            if (birthYear) {
              lifeInfo += formatYear(birthYear);
              if (spouse.alive === 0 && deathYear) {
                lifeInfo += `-${formatYear(deathYear)}`;
              } else if (spouse.alive === 0) {
                lifeInfo += "-?";
              }
            }

            // 返回生卒信息，如果没有则返回空字符串
            if (lifeInfo) {
              if (spouse.alive === 0) {
                return `生卒: ${lifeInfo}`;
              } else {
                return `生: ${lifeInfo}`;
              }
            }
            return "";
          })
          .attr("text-anchor", "middle")
          .attr("x", 0)
          .attr("y", nodeHeight/2 - 140)
          .style("font-family", "'KaiTi', 'SimKai', serif")
          .style("font-size", "14px")
          .style("pointer-events", "none");

        // 在渲染 spouse 节点时，记录坐标
        spousePositionMap.set(spouse.id, {
          x: d.x + xOffset + (i + 1) * spouseSpacing, // spouseGroup的x
          y: d.y + yOffset // spouseGroup的y
        });
      });
    });

    // 遍历所有节点，查找需要母子连线的情况
    root.descendants().forEach(parentNode => {
      if (parentNode.data.children) {
        parentNode.data.children.forEach(child => {
          if (child.motherId) {
            const motherPos = spousePositionMap.get(child.motherId);
            // 找到子节点的 d3 节点
            const childNode = root.descendants().find(n => n.data.id === child.id);
            if (motherPos && childNode) {
              const verticalOffset = 20; // 竖直向下的偏移量
              const motherBottomX = motherPos.x;
              const motherBottomY = motherPos.y + nodeHeight / 2;
              const childTopLeftX = childNode.x + xOffset - nodeWidth / 2;
              const childTopLeftY = childNode.y + yOffset - nodeHeight / 2;

              treeG.append("path")
                .attr("class", "mother-link")
                .attr("d", `
                  M${motherBottomX},${motherBottomY}
                  L${motherBottomX},${motherBottomY + verticalOffset}
                  L${childTopLeftX},${motherBottomY + verticalOffset}
                  L${childTopLeftX},${childTopLeftY}
                `)
                .attr("fill", "none")
                .attr("stroke", "#FF0000")
                .attr("stroke-width", 1)
                .attr("stroke-dasharray", null);
            }
          }
        });
      }
    });
  });
}

// 显示右键菜单
function showContextMenu(event: MouseEvent, d: HierarchyNode<TreeNode>) {
  event.preventDefault();
  event.stopPropagation();

  const [x, y] = [event.pageX, event.pageY];

  // 判断是否为配偶节点（通过检查是否在父节点的spouseList中）
  const isSpouse = d.parent && d.parent.data.spouseList && d.parent.data.spouseList.some(sp => sp.id === d.data.id);
  // 权限判断
  console.log(d.data.familyId,userFamilyId)
  const canEdit = hasAuth(["genealogy:person:edit"]) && (baseFlag === 1 || d.data.familyId === userFamilyId);
  // 判断是否为叶子节点（没有子节点的节点）
  const isLeafNode = !d.data.children || d.data.children.length === 0;
  // 判断是否为顶层节点（没有父亲的节点）
  const isRootNode = !d.data.parentId;
  // 判断是否可以接谱：要么是顶层节点(没有父亲)，要么是叶子节点(没有子节点)
  const canConnectBranch = isLeafNode || isRootNode;
  // 判断是否有关联家谱
  const hasRelatedFamily = d.data.familyRelationList && d.data.familyRelationList.length > 0;

  let menuItems;
  if (isSpouse || !canEdit) {
    menuItems = [
      { action: "edit", label: "查看信息" },
      ...(hasRelatedFamily ? [{ action: "goto-related-family", label: "查看关联家谱" }] : []),
      // 新增：叶子节点允许删除
      ...(isLeafNode && canEdit ? [{ action: "delete", label: "删除成员" }] : [])
    ];
  } else if (d.data.parentId) {
    menuItems = [
      { action: "edit", label: "查看信息" },
      { action: "add-child", label: "新增子辈" },
      { action: "add-spouse", label: "新增配偶" },
      ...(canConnectBranch ? [{ action: "connect-branch", label: "接谱" }] : []),
      ...(hasRelatedFamily ? [{ action: "goto-related-family", label: "查看关联家谱" }] : []),
      isAncestorHidden.value ? { action: "show-ancestor", label: "显示父辈" } : { action: "hide-ancestor", label: "隐藏父辈" },
      // 新增：叶子节点允许删除
      ...(isLeafNode && canEdit ? [{ action: "delete", label: "删除成员" }] : [])
    ];
  } else {
    menuItems = [
      { action: "edit", label: "查看信息" },
      { action: "add-parent", label: "新增父辈" },
      { action: "add-child", label: "新增子辈" },
      { action: "add-spouse", label: "新增配偶" },
      ...(canConnectBranch ? [{ action: "connect-branch", label: "接谱" }] : []),
      ...(hasRelatedFamily ? [{ action: "goto-related-family", label: "查看关联家谱" }] : []),
      // 新增：叶子节点允许删除
      ...(isLeafNode && canEdit ? [{ action: "delete", label: "删除成员" }] : [])
    ];
  }

  menu.html(menuItems.map(item =>
    `<div class="menu-item" data-action="${item.action}">${item.label}</div>`
  ).join(""))
    .style("left", `${x + 10}px`)
    .style("top", `${y + 10}px`)
    .style("display", "block");

  menu.selectAll(".menu-item")
    .on("click", (event) => {
      event.stopPropagation();
      const action = d3.select(event.target as Element).attr("data-action");
      handleMenuAction(action, d);
      menu.style("display", "none");
    });
}

// 处理菜单操作
async function handleMenuAction(action: string, nodeData: HierarchyNode<TreeNode>) {
  // 先处理隐藏/显示父辈，直接执行并返回，不走弹窗逻辑
  if (action === "hide-ancestor") {
    hideAncestorForNode(nodeData);
    return;
  }
  if (action === "show-ancestor") {
    showAncestorTree();
    return;
  }

  // 先处理删除，防止后续弹窗逻辑被触发
  if (action === "delete") {
    ElMessageBox.confirm('确定要删除该成员吗？此操作不可恢复。', '警告', {
      confirmButtonText: '删除',
      cancelButtonText: '取消',
      type: 'warning'
    }).then(async () => {
      try {
        await PersonAPI.deleteByIds(nodeData.data.id);
        ElMessage.success('删除成功');
        // 通知父组件刷新
        emit('node-click', { id: nodeData.data.id }, 99); // type=99表示删除
      } catch (error) {
        ElMessage.error('删除失败：' + (error.message || '未知错误'));
      }
    }).catch(() => {});
    return;
  }

  // 单独处理接谱操作
  if (action === "connect-branch") {
    // 保存当前节点信息
    currentNodeInfo.value = { ...nodeData.data };

    // 设置接谱数据
    connectBranchData.value.sourceId = nodeData.data.id;
    connectBranchData.value.targetId = '';

    // 获取可接谱成员列表
    fetchConnectableMembers(nodeData.data.id);

    // 打开接谱专用对话框
    connectDialog.visible = true;

    return;
  }

  // 新增：单独处理跳转到关联家谱操作
  if (action === "goto-related-family") {
    handleGotoRelatedFamily(nodeData.data);
    return;
  }

  const actionMap = {
    "edit": 0,      // 编辑
    "add-parent": 1,  // 添加父辈
    "add-child": 3,   // 添加子辈
    "add-spouse": 2,   // 添加配偶
  };

  const type = actionMap[action as keyof typeof actionMap];
  const personId = nodeData.data.id;

  if (!personId) {
    ElMessage.warning("无法获取人员ID");
    return;
  }

  try {
    // 获取当前人员信息
    const currentPerson = await PersonAPI.getFormData(personId);

    // 确保保留关联家谱列表信息
    if (nodeData.data.familyRelationList && nodeData.data.familyRelationList.length > 0) {
      currentPerson.familyRelationList = nodeData.data.familyRelationList;
    }

    // 打开弹窗
    dialog.visible = true;
    dialog.type = type;
    if (type == 0){
      formData.value = { ...currentPerson };
      dialog.readonly = true; // 查看信息时默认为只读模式
    }
    formData.value.familyId = currentPerson.familyId;
    formData.value.type = type;
    formData.value.personId = personId;
    // 如果是添加子辈或编辑，需要获取配偶列表作为母亲选项

    if (type === 0) {
      // 获取父节点信息
      const parentNode = nodeData.parent;
      if (parentNode) {
        // 父亲选项（移除性别限制，允许女儿作为父亲）
        const fathers = [parentNode.data, ...(parentNode.data.spouseList || [])];
        fatherOptions.value = fathers.map(father => ({
          value: father.id,
          label: `${father.firstName}${father.lastName}`
        }));
        // 自动赋值parentId
        if (fatherOptions.value.length === 1) {
          formData.value.parentId = fatherOptions.value[0].value;
        }
        // 母亲选项
        const spouses = parentNode.data.spouseList || [];
        motherOptions.value = spouses.map(spouse => ({
          value: spouse.id,
          label: `${spouse.firstName}${spouse.lastName}`
        }));
      }
    }
    if(type === 3 ){
      // 新增子辈时，父亲就是当前节点（无论性别）
      fatherOptions.value = [{
        value: nodeData.data.id,
        label: `${nodeData.data.firstName}${nodeData.data.lastName}`
      }];
      // 自动赋值parentId
      formData.value.parentId = nodeData.data.id;
      // 母亲选项
      const spouses = nodeData.data.spouseList || [];
      motherOptions.value = spouses.map(spouse => ({
        value: spouse.id,
        label: `${spouse.firstName}${spouse.lastName}`
      }));
    }

    // 根据不同类型设置不同的标题和标志
    if (type === 0) {
      dialog.title = "查看成员信息";
    } else if (type === 1) {
      dialog.title = "新增父辈成员信息";
      formData.value.firstName = "李"
    } else if (type === 2) {
      dialog.title = "新增配偶成员信息";
      formData.value.flag = 1;
      // 设置配偶默认性别为与当前节点相反的性别
      formData.value.gender = nodeData.data.gender === 1 ? 2 : 1;
    } else if (type === 3) {
      dialog.title = "新增子辈成员信息";
      formData.value.firstName = "李"
    }
  } catch (error) {
    ElMessage.error("操作失败：" + (error as Error).message);
  }
}

// 在提交前格式化日期
const formatDatesBeforeSubmit = () => {
  if (formData.value.birthYear || formData.value.birthMonth || formData.value.birthDay) {
    const year = formData.value.birthYear?.toString().padStart(4, '0') || '0000';
    const month = formData.value.birthMonth?.toString().padStart(2, '0') || '00';
    const day = formData.value.birthDay?.toString().padStart(2, '0') || '00';
    const hour = formData.value.birthHour?.toString().padStart(2, '0') || '00';
    // 如果是公元前，年份前加负号
    const yearWithEra = formData.value.birthEra === 'BC' ? `-${year}` : year;
    formData.value.birthDate = `${yearWithEra}-${month}-${day} ${hour}`+`:00:00`;
  }

  if (formData.value.deathYear || formData.value.deathMonth || formData.value.deathDay) {
    const year = formData.value.deathYear?.toString().padStart(4, '0') || '0000';
    const month = formData.value.deathMonth?.toString().padStart(2, '0') || '00';
    const day = formData.value.deathDay?.toString().padStart(2, '0') || '00';
    const hour = formData.value.deathHour?.toString().padStart(2, '0') || '00';
    // 如果是公元前，年份前加负号
    const yearWithEra = formData.value.deathEra === 'BC' ? `-${year}` : year;
    formData.value.deathDate = `${yearWithEra}-${month}-${day} ${hour}`+`:00:00`;
  }
};

// 修改原有的提交函数
const handleSubmit = async () => {
  try {
    // 在提交前格式化日期
    formatDatesBeforeSubmit();

    // 提取表单数据，只保留FormData接口中定义的字段
    const submitData = {
      id: formData.value.id,
      firstName: formData.value.firstName,
      lastName: formData.value.lastName,
      gender: formData.value.gender,
      alive: formData.value.alive,
      photoUrl: formData.value.photoUrl,
      motherId: formData.value.motherId,
      flag: formData.value.flag,
      familyId: formData.value.familyId,
      nickname: formData.value.nickname,
      genation: formData.value.genation,
      occupation: formData.value.occupation,
      birthPlace: formData.value.birthPlace,
      address: formData.value.address,
      longitude: formData.value.longitude,
      latitude: formData.value.latitude,
      birthDate: formData.value.birthDate,
      deathDate: formData.value.deathDate,
      biography: formData.value.biography,
      type: formData.value.type,
      personId: formData.value.personId,
      parentId: formData.value.parentId,
      nativePlace: formData.value.nativePlace,
      sortNum: formData.value.sortNum,
      courtesyName: formData.value.courtesyName,
      artName: formData.value.artName,
      backgroundPic: formData.value.backgroundPic,
      emperorNum: formData.value.emperorNum, // 添加帝号字段
      isFounder: formData.value.isFounder || 0, // 确保包含开基祖字段，默认为0
    };

    let apiCall;

    // 处理普通编辑和创建操作
    if (dialog.type === 0) {
      // 编辑操作
      apiCall = PersonAPI.update(submitData.id, submitData);
    } else {
      // 其他创建操作
      apiCall = PersonAPI.createByType(submitData);
    }

    await apiCall;

    let successMsg = dialog.type === 0 ? "修改成功" : "新增成功";
    ElMessage.success(successMsg);
    handleCloseDialog();

    // 触发节点点击事件，通知父组件刷新数据
    emit("node-click", submitData, dialog.type);
  } catch (error) {
    console.error('提交失败：', error);
    ElMessage.error('提交失败：' + (error.message || '未知错误'));
  }
};

/** 启用编辑模式 */
function enableEdit() {
  // 显示确认对话框
  ElMessageBox.confirm('确定要编辑此成员信息吗？', '提示', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'warning'
  }).then(() => {
    // 切换为编辑模式
    dialog.readonly = false;
    dialog.title = "编辑成员信息";
  }).catch(() => {
    // 取消时不做任何操作
  });
}

/** 关闭弹窗 */
function handleCloseDialog() {
  dialog.visible = false;
  dialog.readonly = false; // 重置只读状态

  // 重置表单
  dataFormRef.value?.resetFields();
  dataFormRef.value?.clearValidate();
  formData.value = { ...initialFormData.value };

  dialog.type = 0; // 重置对话框类型
}

// 获取家族选项
onMounted(async () => {
  try {
    const data = await FamilyAPI.getOptions();
    familyOptions.value = data;
  } catch (error) {
    ElMessage.error("获取家族选项失败：" + (error as Error).message);
  }
});


// 判断当前头像是否为默认头像
function isDefaultAvatar(photoUrl, gender, birthDate) {
  return photoUrl === getDefaultAvatar({ gender, birthDate });
}

// 监听性别和出生日期变化，自动更新默认头像
watch(
  () => [formData.value.gender, formData.value.birthDate],
  ([newGender, newBirthDate], [oldGender, oldBirthDate]) => {
    console.log('监控到性别或出生日期变化:', {
      oldGender,
      oldBirthDate,
      newGender,
      newBirthDate
    });
    // 只有当头像是默认头像时才自动更新
    if (isDefaultAvatar(formData.value.photoUrl, oldGender, oldBirthDate)) {
      formData.value.photoUrl = getDefaultAvatar({
        gender: newGender,
        birthDate: newBirthDate,
      });
    }
  }
);

// 监听数据变化
watch(() => [props.modelValue, props.treeList], ([newModelValue, newTreeList]) => {
  if (newTreeList && newTreeList.length > 0) {
    renderTree(newTreeList);
  } else if (newModelValue) {
    renderTree(newModelValue);
  }
}, { deep: true });

// 组件挂载时初始化
onMounted(() => {
  createContextMenu();
  if (props.treeList && props.treeList.length > 0) {
    renderTree(props.treeList);
  } else if (props.modelValue) {
    renderTree(props.modelValue);
  }

  // 添加点击事件监听器来关闭菜单
  d3.select("body").on("click.context-menu", () => {
    if (menu) {
      menu.style("display", "none");
    }
  });

  // 添加延时，确保树渲染完成后再定位到当前用户节点
  setTimeout(() => {
    // 调整定位参数，适应新的高度
    focusOnCurrentUser(800, 200);
  }, 1000);
});

// 新增：定位到当前用户节点的函数，增加微调参数
function focusOnCurrentUser(offsetX: number = 0, offsetY: number = 0, nodeId?: string) {
  // 如果没有指定nodeId，则使用当前用户ID
  const targetId = nodeId || props.currentUserId;

  if (!targetId || !svg) return;

  // 查找目标节点
  const userNode = svg.select(`.node rect[data-user-id="${targetId}"]`);
  if (!userNode.empty()) {
    // 获取节点位置
    const nodeTransform = d3.select(userNode.node().parentNode).attr("transform");
    const match = nodeTransform.match(/translate\(([^,]+),([^)]+)\)/);

    if (match) {
      const x = parseFloat(match[1]) + offsetX;
      const y = parseFloat(match[2]) + offsetY;

      // 计算新的变换，将用户节点居中
      const svgWidth = svg.node().getBoundingClientRect().width;
      const svgHeight = svg.node().getBoundingClientRect().height;

      // 设置固定缩放比例，确保能看到周围的家族成员
      const scale = 0.6; // 缩小比例以便看到更多周围节点

      // 计算新的变换，使用固定缩放比例，并确保用户节点完全居中
      // 添加微调偏移量，允许精确控制位置
      const newX = svgWidth / 2 - x * scale;
      const newY = svgHeight / 2 - y * scale;

      const newTransform = d3.zoomIdentity
        .translate(newX, newY)
        .scale(scale);

      // 平滑过渡到新位置
      svg.transition()
        .duration(750)
        .call(zoom.transform, newTransform)
        .on("end", () => {
          // 跳转完成后，显示同代人数信息
          if (nodeId) {
            // 如果是跳转到特定节点，显示该节点的同代人数信息
            highlightSameGenerationInfo(nodeId);
          } else if (props.currentUserId) {
            // 如果是跳转到当前用户，显示当前用户的同代人数信息
            highlightSameGenerationInfo(props.currentUserId);
          }
        });

      // 保存当前变换，以便后续使用
      currentTransform = newTransform;
    }
  }
}

// 组件卸载前清理
onBeforeUnmount(() => {
  // 清理资源
  if (menu) {
    menu.remove();
  }
  if (svg) {
    svg.selectAll("*").remove();
  }
  d3.select("body").on("click.context-menu", null);
});

function flattenTree(tree): TreeNode[] {
  const result: TreeNode[] = [];
  function traverse(node: TreeNode) {
    if (!node) return;
    result.push(node);
    if (Array.isArray(node.spouseList)) {
      node.spouseList.forEach(sp => result.push(sp));
    }
    if (Array.isArray(node.children)) {
      node.children.forEach(traverse);
    }
  }
  if (Array.isArray(tree)) {
    tree.forEach(traverse);
  } else {
    traverse(tree);
  }
  return result;
}

function searchFather(query) {
  fatherLoading.value = true;

  // 使用本地搜索
  searchLocalMembers(query);
}

// 本地搜索成员 - 从当前家谱树中搜索
function searchLocalMembers(query) {
  setTimeout(() => {
    let allNodes = [];
    if (props.treeList && props.treeList.length > 0) {
      allNodes = flattenTree(props.treeList);
    } else if (props.modelValue) {
      allNodes = flattenTree(props.modelValue);
    }

    // 移除性别限制，允许女儿作为父亲，且排除当前编辑的成员自己
    let fathers = allNodes.filter(item => item.id !== formData.value.id);

    // 关键字过滤
    if (query) {
      fathers = fathers.filter(item =>
        (`${item.firstName || ''}${item.lastName || ''}`.includes(query))
      );
    }

    // 去重
    const map = new Map();
    fathers.forEach(item => {
      if (item.id && !map.has(item.id)) {
        map.set(item.id, item);
      }
    });

    fatherOptions.value = Array.from(map.values()).map(item => ({
      value: item.id,
      label: `${item.firstName || ''}${item.lastName || ''}`,
      source: 'local'
    }));

    // 自动赋值parentId（如果只有一个选项且当前parentId为空）
    if (fatherOptions.value.length === 1 && !formData.value.parentId) {
      formData.value.parentId = fatherOptions.value[0].value;
    }

    fatherLoading.value = false;
  }, 0);
}

function hideAncestorForNode(nodeData: HierarchyNode<TreeNode>) {
  // 缓存原始树数据
  if (!originalTreeData) {
    if (props.treeList && props.treeList.length > 0) {
      originalTreeData = JSON.parse(JSON.stringify(props.treeList));
    } else if (props.modelValue) {
      originalTreeData = JSON.parse(JSON.stringify(props.modelValue));
    }
  }
  // 只保留当前节点及其后代，去掉父辈
  function deepCloneNode(node: HierarchyNode<TreeNode>): TreeNode {
    const { data, children } = node;
    const clone: TreeNode = { ...data };
    if (children && children.length > 0) {
      clone.children = children.map(child => deepCloneNode(child));
    }
    return clone;
  }
  const newTree = deepCloneNode(nodeData);
  isAncestorHidden.value = true;
  renderTree(newTree);

  // 添加延时，确保树重新渲染完成后再定位到当前节点
  setTimeout(() => {
    // 使用当前节点ID进行聚焦，调整参数
    focusOnCurrentUser(800, 200, nodeData.data.id);
  }, 1000);
}

function showAncestorTree() {
  if (originalTreeData) {
    isAncestorHidden.value = false;
    renderTree(originalTreeData);
    originalTreeData = null;

    // 添加延时，确保树重新渲染完成后再定位到当前用户节点
    setTimeout(() => {
      focusOnCurrentUser(800, 200);
    }, 1000);
  }
}

// 新增：计算节点的代数，考虑开基祖
function calculateGeneration(node: d3.HierarchyNode<TreeNode>): { generation: number, founderName?: string } {
  // 如果当前节点是开基祖，返回1
  if (node.data.isFounder === 1) {
    return {
      generation: 1,
      founderName: `${node.data.lastName || ''}`
    };
  }

  // 从当前节点向上查找最近的开基祖
  let currentNode = node;
  let generation = 0; // 默认值改为0，表示没有代数
  let foundFounder = false;
  let founderDepth = 0;
  let founderName = '';

  while (currentNode.parent) {
    currentNode = currentNode.parent;
    // 如果找到开基祖，从开基祖重新计算代数
    if (currentNode.data.isFounder === 1) {
      founderDepth = currentNode.depth;
      foundFounder = true;
      founderName = `${currentNode.data.lastName || ''}`;
      break;
    }
  }

  // 如果找到了开基祖，返回相对于开基祖的代数
  if (foundFounder) {
    // 修正计算逻辑：开基祖是第1代，其子代是第2代，以此类推
    return {
      generation: node.depth - founderDepth + 1,
      founderName: founderName
    };
  }

  // 如果没有找到开基祖，返回0，表示没有代数
  return { generation: 0 };
}

// 新增：计算同代成员数量的函数
function countSameGenerationMembers(node: d3.HierarchyNode<TreeNode>): number {
  if (!node || !node.parent) return 1; // 如果是根节点，只有自己一个

  // 获取当前节点的世系（depth）
  const currentDepth = node.depth;

  // 获取整棵树的所有节点
  let allNodes: d3.HierarchyNode<TreeNode>[] = [];
  // 从根节点开始收集
  let rootNode = node;
  while (rootNode.parent) {
    rootNode = rootNode.parent;
  }

  // 递归收集所有节点
  function collectNodes(n: d3.HierarchyNode<TreeNode>) {
    allNodes.push(n);
    if (n.children) {
      n.children.forEach(collectNodes);
    }
  }

  collectNodes(rootNode);

  // 过滤出同世系节点（具有相同depth的节点）
  const sameDepthNodes = allNodes.filter(n => n.depth === currentDepth);

  return sameDepthNodes.length;
}

// 添加一个导出的方法，允许父组件调用微调
defineExpose({
  focusOnCurrentUser
});

// 搜索相关状态
const searchQuery = ref('');
const searchResults = ref<Array<TreeNode>>([]);
const allNodesFlat = ref<Array<TreeNode>>([]);

// 搜索处理函数
function handleSearchInput() {
  if (!searchQuery.value || searchQuery.value.length < 1) {
    searchResults.value = [];
    return;
  }

  // 确保平铺节点数组已初始化
  if (allNodesFlat.value.length === 0) {
    updateFlatNodesList();
  }

  // 搜索逻辑
  const query = searchQuery.value.toLowerCase();
  searchResults.value = allNodesFlat.value
    .filter(node => {
      const fullName = `${node.firstName || ''}${node.lastName || ''}`.toLowerCase();
      const genation = (node.genation || '').toLowerCase();
      const nickname = (node.nickname || '').toLowerCase();
      const occupation = (node.occupation || '').toLowerCase();

      return fullName.includes(query) ||
        genation.includes(query) ||
        nickname.includes(query) ||
        occupation.includes(query);
    })
    .slice(0, 10); // 限制结果数量
}

// 清除搜索
function clearSearch() {
  searchQuery.value = '';
  searchResults.value = [];
}

// 更新平铺节点列表
function updateFlatNodesList() {
  allNodesFlat.value = [];
  if (props.treeList && props.treeList.length > 0) {
    props.treeList.forEach(tree => {
      allNodesFlat.value = [...allNodesFlat.value, ...flattenTree(tree)];
    });
  } else if (props.modelValue) {
    allNodesFlat.value = flattenTree(props.modelValue);
  }
}

// 聚焦到搜索结果
function focusOnSearchResult(node: TreeNode) {
  if (!node.id) return;

  // 使用已有的focusOnCurrentUser函数来定位，传入水平和垂直偏移参数
  focusOnCurrentUser(800, 200, node.id);

  // 高亮显示搜索结果
  highlightSearchResult(node.id);

  // 高亮显示同代人数信息
  highlightSameGenerationInfo(node.id);

  // 清除搜索结果
  clearSearch();
}

// 新增：高亮显示同代人数信息
function highlightSameGenerationInfo(nodeId: string) {
  // 查找目标节点的rect元素，然后找到其父节点（.node组）
  const targetRect = svg.select(`rect[data-user-id="${nodeId}"]`);
  if (!targetRect.empty()) {
    const nodeGroup = d3.select(targetRect.node().parentNode);
    const sameGenText = nodeGroup.select('.same-generation-info');
    
    if (!sameGenText.empty()) {
      // 先显示同代人数信息
      sameGenText.style("opacity", 1);
      
      // 添加高亮效果
      sameGenText
        .style("fill", "#FF0000") // 改为红色
        .style("font-size", "16px") // 增大字体
        .style("font-weight", "bold")
        .style("filter", "drop-shadow(0px 0px 3px rgba(255, 0, 0, 0.5)"); // 添加红色光晕
      
      // 3秒后只恢复样式，但保持显示状态
      setTimeout(() => {
        sameGenText
          .style("fill", "#b97a00")
          .style("font-size", "14px")
          .style("filter", "none");
        // 移除 opacity: 0，保持显示状态
      }, 3000);
    }
  }
}

// 高亮显示搜索结果
function highlightSearchResult(nodeId: string) {
  // 先重置所有节点的高亮状态
  svg.selectAll(".node rect")
    .style("stroke-width", d => {
      if (d.data.emperorNum) return 4; // 保持帝号节点的粗边框
      return d.data.id === props.currentUserId ? 4 : 2;
    })
    .style("filter", d => {
      if (d.data.emperorNum) {
        return "drop-shadow(0px 0px 8px rgba(255, 153, 0, 0.5))"; // 保持帝号节点的金色光晕
      }
      if (d.data.id === props.currentUserId) {
        return "drop-shadow(0px 0px 8px rgba(255, 0, 0, 0.5))"; // 红色光晕
      }
      return "drop-shadow(0px 2px 3px rgba(0, 0, 0, 0.2))";
    });

  // 高亮搜索结果节点
  svg.select(`.node rect[data-user-id="${nodeId}"]`)
    .style("stroke-width", 4)
    .style("filter", "drop-shadow(0px 0px 12px rgba(255, 0, 0, 0.7))");

  // 3秒后恢复正常显示
  setTimeout(() => {
    const nodeElement = svg.select(`.node rect[data-user-id="${nodeId}"]`);
    if (!nodeElement.empty()) {
      const d = d3.select(nodeElement.node().parentNode).datum();
      nodeElement
        .style("stroke-width", () => {
          if (d.data.emperorNum) return 4; // 恢复帝号节点的粗边框
          return nodeId === props.currentUserId ? 4 : 2;
        })
        .style("filter", () => {
          if (d.data.emperorNum) {
            return "drop-shadow(0px 0px 8px rgba(255, 153, 0, 0.5))"; // 恢复帝号节点的金色光晕
          }
          return nodeId === props.currentUserId ?
            "drop-shadow(0px 0px 8px rgba(255, 0, 0, 0.5))" : // 红色光晕
            "drop-shadow(0px 2px 3px rgba(0, 0, 0, 0.2))";
        });
    }
  }, 3000);
}

// 监听树数据变化，更新平铺节点列表
watch(() => [props.modelValue, props.treeList], () => {
  updateFlatNodesList();
}, { deep: true });

// 新增：处理跳转到关联家谱
function handleGotoRelatedFamily(node: TreeNode) {
  if (!node.familyRelationList || node.familyRelationList.length === 0) {
    ElMessage.warning("该成员没有关联家谱");
    return;
  }

  // 如果只有一个关联家谱，直接跳转
  if (node.familyRelationList.length === 1) {
    const relation = node.familyRelationList[0];
    navigateToRelatedFamily(relation, node.id);
    return;
  }

  // 如果有多个关联家谱，弹出选择框
  ElMessageBox.confirm(
    `<div class="related-family-list">
      ${node.familyRelationList.map((relation, index) => {
      // 判断当前节点是源节点还是目标节点
      const isTarget = node.id && relation.targetPersonId === node.id;
      const familyName = isTarget ? relation.sourceFamilyName : relation.targetFamilyName;

      return `
          <div class="related-family-item" data-index="${index}">
            <div class="family-name">${familyName || '未命名家谱'}</div>
            <div class="family-remark">${relation.auditRemark || ''}</div>
          </div>
        `;
    }).join('')}
    </div>`,
    '请选择要跳转的关联家谱',
    {
      confirmButtonText: '取消',
      cancelButtonText: '关闭',
      dangerouslyUseHTMLString: true,
      showCancelButton: true,
      showConfirmButton: false,
      customClass: 'related-family-dialog'
    }
  ).catch(() => {
    // 不做任何处理
  });

  // 添加点击事件处理
  setTimeout(() => {
    const items = document.querySelectorAll('.related-family-item');
    items.forEach(item => {
      item.addEventListener('click', () => {
        const index = parseInt(item.getAttribute('data-index') || '0');
        // 先尝试关闭对话框，再导航
        ElMessageBox.close();
        setTimeout(() => {
          navigateToRelatedFamily(node.familyRelationList![index], node.id);
        }, 100);
      });
    });
  }, 100);
}

// 新增：导航到关联家谱
function navigateToRelatedFamily(relation: FamilyRelation, currentNodeId?: string) {
  // 确保任何打开的消息框都被关闭
  try {
    ElMessageBox.close();
  } catch (e) {
    // 忽略可能的错误
  }

  // 判断当前节点是源节点还是目标节点
  const isTarget = currentNodeId && relation.targetPersonId === currentNodeId;

  // 根据当前节点角色选择要跳转的节点ID和家谱名称
  const personId = isTarget ? relation.sourcePersonId : relation.targetPersonId;
  const familyName = isTarget ? relation.sourceFamilyName : relation.targetFamilyName;

  // 发出事件通知父组件处理跳转
  router.push({
    name: "FamilyShow",
    params: { personId: personId },
    query: { type: "nine" },
  });

  ElMessage.success(`正在跳转到关联家谱: ${familyName}`);
}

// 在 watch 中添加对 birthDate 和 deathDate 的监听
watch(() => formData.value.birthDate, (newVal) => {
  if (newVal) {
    // 检查是否为负数年份（公元前）
    const isBC = newVal.startsWith('-');
    formData.value.birthEra = isBC ? 'BC' : 'AD';

    // 解析日期，处理可能的负数年份
    let dateStr = newVal;
    if (isBC) {
      dateStr = dateStr.substring(1); // 移除负号
    }
    const date = new Date(dateStr);

    // 设置年月日，确保使用绝对值
    formData.value.birthYear = Math.abs(date.getFullYear()).toString();
    formData.value.birthMonth = (date.getMonth() + 1).toString();
    formData.value.birthDay = date.getDate().toString();
    formData.value.birthHour = date.getHours().toString();
  }
}, { immediate: true });

watch(() => formData.value.deathDate, (newVal) => {
  if (newVal) {
    // 检查是否为负数年份（公元前）
    const isBC = newVal.startsWith('-');
    formData.value.deathEra = isBC ? 'BC' : 'AD';

    // 解析日期，处理可能的负数年份
    let dateStr = newVal;
    if (isBC) {
      dateStr = dateStr.substring(1); // 移除负号
    }
    const date = new Date(dateStr);

    // 设置年月日，确保使用绝对值
    formData.value.deathYear = Math.abs(date.getFullYear()).toString();
    formData.value.deathMonth = (date.getMonth() + 1).toString();
    formData.value.deathDay = date.getDate().toString();
    formData.value.deathHour = date.getHours().toString();
  }
}, { immediate: true });

// 添加日期限制和处理函数
const handleYearInput = (type: 'birth' | 'death') => {
  const yearValue = type === 'birth' ? formData.value.birthYear : formData.value.deathYear;
  if (yearValue) {
    const maxYear = 4000;
    const minYear = 1;
    const numValue = parseInt(yearValue);
    if (numValue > maxYear) {
      if (type === 'birth') {
        formData.value.birthYear = maxYear.toString();
      } else {
        formData.value.deathYear = maxYear.toString();
      }
    } else if (numValue < minYear) {
      if (type === 'birth') {
        formData.value.birthYear = minYear.toString();
      } else {
        formData.value.deathYear = minYear.toString();
      }
    }
  }
};

const handleMonthInput = (type: 'birth' | 'death') => {
  const monthValue = type === 'birth' ? formData.value.birthMonth : formData.value.deathMonth;
  if (monthValue) {
    const numValue = parseInt(monthValue);
    if (numValue > 12) {
      if (type === 'birth') {
        formData.value.birthMonth = '12';
      } else {
        formData.value.deathMonth = '12';
      }
    } else if (numValue < 1) {
      if (type === 'birth') {
        formData.value.birthMonth = '1';
      } else {
        formData.value.deathMonth = '1';
      }
    }
  }
};

const handleDayInput = (type: 'birth' | 'death') => {
  const dayValue = type === 'birth' ? formData.value.birthDay : formData.value.deathDay;
  if (dayValue) {
    const numValue = parseInt(dayValue);
    if (numValue > 31) {
      if (type === 'birth') {
        formData.value.birthDay = '31';
      } else {
        formData.value.deathDay = '31';
      }
    } else if (numValue < 1) {
      if (type === 'birth') {
        formData.value.birthDay = '1';
      } else {
        formData.value.deathDay = '1';
      }
    }
  }
};

const handleHourInput = (type: 'birth' | 'death') => {
  const dayValue = type === 'birth' ? formData.value.birthHour : formData.value.deathHour;
  if (dayValue) {
    const numValue = parseInt(dayValue);
    if (numValue > 23) {
      if (type === 'birth') {
        formData.value.birthHour = '23';
      } else {
        formData.value.deathHour = '23';
      }
    } else if (numValue < 0) {
      if (type === 'birth') {
        formData.value.birthHour = '0';
      } else {
        formData.value.deathHour = '0';
      }
    }
  }
};

// 添加定位到当前用户的方法
function locateCurrentUser() {
  // 使用已有的focusOnCurrentUser函数，传入适当的偏移量
  focusOnCurrentUser(800, 200);

  // 添加动画效果，提示用户已定位
  const locateBtn = document.querySelector('.locate-button');
  if (locateBtn) {
    locateBtn.classList.add('animate-pulse');
    setTimeout(() => {
      locateBtn.classList.remove('animate-pulse');
    }, 1000);
  }
}
</script>

<style scoped>
.d3-chart {
  width: 100%;
  height: calc(100vh - 150px); /* 修改为视口高度减去导航栏高度 */
  min-height: 500px; /* 减小最小高度 */
  position: relative;
  background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" opacity="0.08"><path d="M0,0 L100,100 M100,0 L0,100" stroke="%23654321" stroke-width="1"/></svg>');
  background-color: #f9f6ef;
  border: 1px solid #d9c7a7;
  border-radius: 5px;
  box-shadow: 0 0 15px rgba(0, 0, 0, 0.05);
}

/* 添加定位按钮样式 */
.locate-button {
  position: absolute;
  bottom: 20px;
  right: 20px;
  width: 40px;
  height: 40px;
  background-color: rgba(253, 245, 230, 0.9);
  border: 1px solid #d9c7a7;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
  z-index: 1000;
  transition: all 0.3s;
}

.locate-button:hover {
  background-color: #f5efe0;
  transform: scale(1.1);
}

.locate-button i {
  font-size: 20px;
  color: #8B4513;
}

/* 添加搜索框样式 */
.search-container {
  position: fixed;
  top: 180px; /* 减小顶部距离 */
  right: 100px;
  width: 250px;
  z-index: 1000;
  background-color: rgba(253, 245, 230, 0.9);
  border: 1px solid #d9c7a7;
  border-radius: 8px;
  padding: 10px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
  backdrop-filter: blur(5px);
  transition: all 0.3s ease;
}

.search-container:hover {
  background-color: rgba(253, 245, 230, 1);
  box-shadow: 0 6px 16px rgba(0, 0, 0, 0.2);
}

.search-results {
  position: absolute;
  top: 100%;
  left: 0;
  width: 100%;
  max-height: 300px;
  overflow-y: auto;
  background-color: #fdf5e6;
  border: 1px solid #d9c7a7;
  border-radius: 4px;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.15);
  z-index: 1001;
  margin-top: 5px;
}

.search-result-item {
  display: flex;
  align-items: center;
  padding: 8px 12px;
  cursor: pointer;
  border-bottom: 1px dashed #e5d9c3;
}

.search-result-item:last-child {
  border-bottom: none;
}

.search-result-item:hover {
  background-color: #f5efe0;
}

.result-avatar {
  width: 32px;
  height: 32px;
  border-radius: 50%;
  margin-right: 10px;
  object-fit: cover;
  border: 1px solid #d9c7a7;
}

.result-info {
  display: flex;
  flex-direction: column;
}

.result-name {
  font-size: 14px;
  font-weight: bold;
  color: #8B4513;
}

.result-extra {
  font-size: 12px;
  color: #999;
}
</style>

<style>
/* 右键菜单样式 - 移到全局样式确保能应用到body下的元素 */
#d3-context-menu {
  background: #fdf5e6;
  border-radius: 8px;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.15);
  padding: 8px 0;
  min-width: 160px;
  font-family: 'SimSun', 'FangSong', serif;
  border: 1px solid #d9c7a7;
  z-index: 9999;
}

#d3-context-menu .menu-item {
  padding: 10px 16px;
  color: #8B4513;
  font-size: 14px;
  cursor: pointer;
  transition: all 0.2s;
  display: flex;
  align-items: center;
}

#d3-context-menu .menu-item:hover {
  background: #f5efe0;
  color: #8B0000;
}

#d3-context-menu .menu-item:active {
  background: #e5d9c3;
}

/* 关联家谱对话框样式 */
.related-family-dialog .el-message-box__content {
  padding: 10px 15px;
}

.related-family-list {
  max-height: 300px;
  overflow-y: auto;
}

.related-family-item {
  padding: 10px;
  margin: 5px 0;
  border: 1px solid #d9c7a7;
  border-radius: 5px;
  cursor: pointer;
  background-color: #fffaf0;
  transition: all 0.2s;
}

.related-family-item:hover {
  background-color: #f5efe0;
  border-color: #ff9900;
}

.related-family-item .family-name {
  font-weight: bold;
  color: #8B4513;
  font-size: 16px;
  margin-bottom: 5px;
}

.related-family-item .family-remark {
  color: #666;
  font-size: 14px;
}
</style>

<style scoped>
/* 连接线样式 */
.link {
  transition: stroke 0.3s;
}

/* 节点样式 */
.node rect {
  transition: fill 0.3s, stroke 0.3s;
}

.node:hover rect {
  fill: #f5efe0;
}

/* 配偶节点样式 */
.spouse-node:hover rect {
  fill: #f5e0ef;
}

.collapse-button {
  transition: all 0.3s;
}

.collapse-button:hover {
  fill: #f5efe0;
}

.collapse-icon {
  font-size: 16px;
  font-weight: bold;
}

/* 节点头部收缩按钮样式 */
.node-collapse-button {
  transition: all 0.3s;
}

.node-collapse-button:hover {
  fill: #f5efe0;
}

.node-collapse-icon {
  font-size: 16px;
  font-weight: bold;
}

/* 族谱特有样式 */
.el-drawer {
  background-color: #fdf5e6 !important;
  border-left: 1px solid #d9c7a7;
}

.el-form-item__label {
  font-family: 'KaiTi', 'SimKai', serif !important;
  color: #8B4513 !important;
  font-size: 16px !important;
}

.el-input__inner {
  background-color: #fffaf0 !important;
  border-color: #d9c7a7 !important;
}

.el-button--primary {
  background-color: #8B4513 !important;
  border-color: #8B4513 !important;
}

.el-button--primary:hover {
  background-color: #A0522D !important;
  border-color: #A0522D !important;
}

.el-button:not(.el-button--primary) {
  background-color: #f5efe0 !important;
  border-color: #d9c7a7 !important;
  color: #8B4513 !important;
}

.el-button:not(.el-button--primary):hover {
  background-color: #e5d9c3 !important;
  border-color: #c9b797 !important;
}

.dialog-footer {
  border-top: 1px dashed #d9c7a7;
  padding-top: 15px;
}

/* 接谱相关样式 */
.connect-branch-container {
  padding: 0 20px;
}

.selected-node-info,
.connect-branch-option {
  display: flex;
  align-items: center;
}

.node-avatar,
.option-avatar {
  width: 32px;  /* 原来是40px */
  height: 32px; /* 原来是40px */
  border-radius: 50%;
  margin-right: 10px;
  object-fit: cover;
  border: 1px solid #d9c7a7;
}

.option-avatar {
  width: 24px;  /* 下拉选项中的头像更小 */
  height: 24px;
}

.node-details,
.option-details {
  display: flex;
  flex-direction: column;
}

.node-name,
.option-name {
  font-size: 14px;
  font-weight: bold;
  color: #333;
}

.node-extra,
.option-extra {
  font-size: 12px;
  color: #999;
  margin-top: 2px;
}

/* 修改接谱选项样式，强调家谱名称和重合人数 */
.connect-branch-option {
  display: flex;
  align-items: center;
}

.option-details {
  display: flex;
  flex-direction: column;
  width: 100%;
}

.option-name {
  font-size: 14px;
  font-weight: bold;
  color: #333;
}

.option-extra {
  font-size: 12px;
  color: #666;
  margin-top: 2px;
}

.family-name {
  color: #1890ff;
  font-weight: bold;
}

.overlap-count {
  color: #ff4d4f;
  font-weight: bold;
}

/* 表单提示样式 */
.form-tip {
  margin-left: 10px;
  font-size: 12px;
  color: #909399;
}

/* 关系图容器样式 */
.relation-tree-container {
  margin-top: 20px;
  margin-bottom: 20px;
  width: 100%;
  height: 400px;
  border: 1px solid #d9c7a7;
  border-radius: 8px;
  overflow: hidden;
  background-color: #fdf5e6;
  position: relative;
}

.result-generation {
  font-size: 14px;
  color: #999;
}

</style>

<style lang="scss" scoped>
// ... existing styles ...
.date-input-group {
  display: flex;
  align-items: center;
  width: 100%;

  .el-select {
    width: 110px;
    margin-right: 8px;
  }
  .year-input {
    width: 80px;
    margin-right: 8px;
    flex: none;
  }
  .month-input {
    width: 32px;
    margin-right: 8px;
    flex: none;
  }
  .day-input {
    width: 40px;
    margin-right: 8px;
    flex: none;
  }
  .hour-input {
    width: 70px;
    margin-right: 0;
    flex: none;
  }
  :deep(.el-input__inner) {
    text-align: center;
  }
}
</style>

<style>
/* ... existing styles ... */

/* 添加定位按钮的动画效果 */
@keyframes pulse {
  0% { transform: scale(1); }
  50% { transform: scale(1.2); }
  100% { transform: scale(1); }
}

.animate-pulse {
  animation: pulse 1s ease-in-out;
}
</style>

<style scoped>
.loading-container {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
  font-size: 14px;
  color: #8B4513;
}

.loading-container .is-loading {
  margin-right: 10px;
}
</style>

